* Replace usages of `Timex.to_unix` with native API
* Wrap call to `Timex.is_valid_timezone?`
* Wrap calls to `Timex.today(tz)`
* Replace `Timex.today()` with `Date.utc_today()`
* Replace `Timex.now()` with `DateTime.utc_now()`
* Replace `Timex.compare` with `Date.compare`
* Wrap `Timex.diff` calls
* Replace `Timex.Timezone.convert` with `DateTime.shift_zone!`
* Wrap `Timex.parse!`
* Replace `Timex.to_date` with native API calls
* Replace `Timex.beginning|end_of...` with native API calls for Date
* Wrap `Timex.beginning|end_of...` for DateTimes and Dates for years
* Replace `Timex.format(!)` with native API calls
* Replace `Timex.to_naive_datetime` with native API calls
* Wrap time humanizing routines using Timex
* Remove unnecessary `use Timex` instances
* Replace `Timex.shift` with native API calls
* Make `QueryParser.parse_date` handle gaps and ambiguities gracefully
* Replace `Timex.now(tz)` with `DateTime.now!(tz)`
* Use a more suitable Date function for comparison (h/t @aerosol)
* Refactor tracker config IDs to contain prefix 'pa-' in the DB
* Test
* Add NanoidBase behaviour
* Refactor to case
* Verify that only the ID changes
* Fix broken if block, add test
* 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
* 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
* 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
* 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>
* 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
* 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
* Comment out legacy fields and relationships
* WIP
* WIP 2
* WIP 3
* wip
* Remove teams backfill and consistency check scripts
* WIP 3
* Fix CheckUsage tests
* Update billing/subscription tests
* WIP 4
* Make site transfer fail if some invitation already exists
* Fixup: do symmetric invitation/site transfer check
* Update UI bugs: make listing sites/inviting admins work like before
* Fix Sites test
* Fix external sites controller test
* Fix live sites tests
* Fix props availability lookup
* Fix site controller tests
* Fix billing controller tests
* WIP - accept invitation tests
* Another round of test fixes + invitations logic bugs
* users_test -> teams_test
* Update registration via invitation
Here, we still rely on "polymorphic" invitation structures,
hence the "unified by id" helper.
For now, it'll remain local unless we discover it's
needed in the broader `Teams.Invitations` context.
cc @zoldar
* Yet another round of test and bugfixes along the way
* Include team in site setup success e-mail
* Fix send_site_setup_emails worker
* Fixed almost all tests except CRM ones
* Update enterprise plan admin test
* Fix CRM + remaining tests
* Address credo warnings (modulo one FIXME)
* Remove last FIXME and rephrase the invitation test case description
* Set Team fields via User CRM transparently
* Map user reference in Enterprise Plan CRM via team owner
* Fix resource actions in user CRM
* Get rid of warning when opening create form in API keys CRM
* Stop emitting warnings when editing Enterprise Plans via CRM
* Tests: Bump await_clickhouse_count interval
* Remove XXX marker
* Fix register from invitation link in email sent for ownership transfer
* Simplify fetching all pending site ownership site IDs
* Remove commented out schema fields
* Remove unused functions
* Address flakiness in ingest counter tests
* Remove unused `Teams.Sites.create`
* Don't restart trial on team with subscription when creating site
* Account for cases of legacy teams with empty trial expiry date
* Revert "Address flakiness in ingest counter tests"
This reverts commit 60dc1e4115.
* Fix flaky ingest counters tests under load
* Attempt 2
* Pre-emptively hardcode site ids in sampling cache test
to avoid supplying the same IDs alongside with counters test,
that inserts through another repo (async).
what we're observing is, clickhouse not summing mergetree columns fast
enough, even though we wait quite a bit.
* Fix ingest counter tests by accounting for delayed summation
---------
Co-authored-by: Adam Rutkowski <hq@mtod.org>
* ingest missing pageleave as 255 for pageleave events
* return scroll depth as nil when no valid pageleave data in range
* also set empty comparison value as nil instead of 0
* add data migration
In production we use `storage_policy = 'tiered'` by default but this is
not reflected in any migrations.
This change fixes that by introducing a new environment variable and
plumbing to be used in new (and old) migrations
Tested via setting env, doing `mix ecto.drop; mix ecto.create; mix ecto.migrate` and
checking resulting table schemas.
* Modify test utils to use teams test factories
* Implement alternative routes for updating and removing membership
* Implement teams read adapter for listing site members and invitees
* Use new teams read adapter for Settings > People view
* Add `invitation_id` column to `guest_invitations` schema
* Add `invitation_id` to `GuestInvitation` schema and populate it
* Sync guest invitation's invitation ID instead of team invitation
* Expose guest invitation's invitation ID in sites list
* Sync guest invitation invitation ID instead of team invitation in backfill
* Update team consistency check to account for guest invitation IDs
* Remove workaround for no invitation ID on guest invitation in `list_people`
* Test listing pending invitations
* Test listing memberships
* Format
* Test membership changes via new routes
* Remove old membership altering routes
* Clean up
* Revert "Modify test utils to use teams test factories"
This reverts commit 5eb8754782.
* Ensure test setup provisions teams for people listing
* See if we can avoid exposing user id
* Revert "See if we can avoid exposing user id"
This reverts commit 672429b9d1.
* Fix faulty member label in people list
* Fix sites listing for a case of pending invite with existing pin
---------
Co-authored-by: hq1 <hq@mtod.org>
* Channels: Migration to add column, backfill code
This change adds `acqusition_channel` columns to events_v2 and
sessions_v2 tables. These columns are materialized - we don't ingest
into them directly. Instead they're calculated based on other columns.
The data migration changes now allow to also backfill the column.
Tested the ability to change definitions by changing the function
definitions and re-running the migration with backfill. Confirmed that
the underlying data changed as expected.
* quiet option
* Exclude data migrations from validation
* Migration consistency
* Channels: Fix cluster behavior
CREATE TABLE AS SELECT syntax did not work on cluster.
Instead, let's do a normal insert. For safety and to avoid timing
issues, ensure that INSERT waits for data to be inserted on all active
replicas.
* Proper replicated tables
* Fix interpolation in data_migration.ex
* Speed up calculating acquisition_channel in clickhouse
The previous `has` queries proved to be problematic and causing a lot of
CPU overhead.
Benchmarked via this query:
```sql
SELECT
channel,
count(),
countIf(acquisition_channel(referrer_source, utm_medium, utm_campaign, utm_source, click_id_param) = channel) AS matches
FROM events_v2
WHERE timestamp > now() - toIntervalHour(48)
GROUP BY channel
ORDER BY count() desc
```
Before this fix:
```
query_duration_ms: 57960
DiskReadElapsedMs: 374.712
RealTimeMs: 2891200.667
UserTimeMs: 2704024.783
SystemTimeMs: 1693.265
OSCPUWaitMs: 90.253
OSCPUVirtualTimeMs: 2705709.58
```
After this fix:
```
query_duration_ms: 4367
DiskReadElapsedMs: 454.356
RealTimeMs: 213892.207
UserTimeMs: 199363.485
SystemTimeMs: 1479.364
OSCPUWaitMs: 13.739
OSCPUVirtualTimeMs: 200837.37
```
Note that the new tables are not tracked in our schema as usual as
they're pretty much temporary tables to create the dictionary without
needing to upload files to clickhouse servers.
* CREATE OR REPLACE table with SELECT
* Implement user owning existing and pending sites check for teams
* Add predicate checking whether user has any existin or pending sites via teams
* Check need to upgrade for sites list via teams when FF is up
* Backfill teams for users on trial without a team
* Create team for users who register with trial started
* Replicate trial start logic on user create in team factories
* Make `ensure_can_take_ownership` in sites LV work via teams too
* Dispatch feature access check from `/sites` to Teams-schema reads
---------
Co-authored-by: Adam Rutkowski <hq@mtod.org>
* Expose a few data migration functions, add quiet option to do_run
* Create functions and test acquisition channel logic in clickhouse
Tests were lifted from test/plausible_web/controllers/api/external_controller_test.exs
* Clean up test code a bit
* Property test for acquisition channels
* Handle empty strings properly in reference implementation
* Fix spelling, minor issues
* Revert "Property test for acquisition channels"
This reverts commit 3fa0e0e4eb.
* Only test clickhouse functions
* Solve minor code issue
* update channels logic
* Revert "Only test clickhouse functions"
This reverts commit e12784031a.
* Add more tests
* Add small result assertion
* Make query options explicit in data migrations
* Move multi-query running logic to within datamigration lib
* Unbreak numeric ids migration
* Named params directly to Clickhouse
* Update reference test implementation
---------
Co-authored-by: Uku Taht <uku.taht@gmail.com>
* Clean site transfers after 48 hours
* Sync accepting site transfers and invitations within transaction
* Add dry run mode to teams backfill and make it a default
* Extend invitation clean worker tests
* Extend team consistency checks
* Sync team against user right after creating the site
* Prune orphaned team guest memberships and invitations on site removal
* Ensure team is present before use in sync logic
* Ensure teams backfill works against partially assigned sites
* Associate site with team on creation
* Associate site with team on sync
* Reuse alias
* Add tests for invitation creation sync
* Move team assertions to a helper module
* Format
* Test team creation on site creation via Sites context module
* Add tests for teams sync on subscription changes
* Tag tests
* Test grace period start syncing up with teams
* Test grace period manual lock sycning w/ teams
* Test grace period end sycing up w/ teams
* Test clearing grace period sync with teams
* Update moduledoc
* Fix missing preloads and wrong result pattern matching in sync logic
* Test sync on accepting invites and site transfers
* Test sync on membership role update and member removal
* transfer async fix WIP
* Stop privisioning team in site factory
* Remove unused relationship from Site schema
* Ensure consistent parsing of `passthrough` from Paddle webhook
* Update team passthrough notification tests & logic
---------
Co-authored-by: Adam Rutkowski <hq@mtod.org>
* Extend schemas with new fields and relationships for teams
* Implement listing sites and sites with invitations with teams
* Implement creating invitations with teams
* Implement accepting invites with teams
* Add `Teams.SiteTransfer` schema
* Implement creating ownership transfers
* Implement accepting site transfer between teams
* Make results shapes from `Teams.Memberships` role functions more consistent
* Remove :team relation from ApiKey schema
* Pass and provision team on subscription creation
* Pass and provision team on enterprise plan creation
* Implement creating site for a team
* Keep team in sync during legacy ownership transfer and invitations
* Resolve conflict in `Teams.get_or_create` without transaction
* Abstract `GracePeriod` manipulation behind `Plausible.Users`
* Put `User.start_trial` behind `Plausible.Users` API
* Sync team fields on user update, if team exists
* Sync cleaning invitations, updating and removing members
* Transfer invitations too
* Implement backfill script
* Allow separate pg repo for backfill script
* Rollback purposefully at the end
* Update backfill script with parallel processing
* Use `IS DISTINCT FROM` when comparing nullable fields
* Handle no teams to backfill case gracefully when reporting
* Parallelize guest memberships backfill
* Remove transaction wrapping and query timeouts
* Make team sync check more granular and fix formatting
* Wrap single team backfill in a transatction for consistent restarts
* Make invitation and site transfer backfills preserve invitation ID
* Update migration repo config for easier dev access
* Backfill teams for users with subscriptions without sites
* Log timestamps
* Put teams sync behind a compile-time flag
* Keep timestamps in sync and fix subscriptions backfill
* Fix formatting
* Make credo happy
* Don't `use Plausible.Migration` to avoid dialyzer complaining
None of the tooling from there is used anywhere and `@repo` can
be defined directly in the migration script.
* Drop SSL workarounds in the backfill script
---------
Co-authored-by: Adam Rutkowski <hq@mtod.org>
* Migration: add installation meta
* Update site schema with installation meta
* Remove VERIFICATION_ENABLED env var
* Add context API to create/remove special goals
* Add context api to update installation meta
* Remove verification enabled check
* Update new progress flow definitions
* Update generic components
* Remove internal /status API
* Implement installation live view
* Update traffic change notifier link
* Update verification, no more modal
* Update routes
* Remove focus.html - will unify everything under app layout
* Fix broken link
* Update templates with focus_box mostly
* Update controller tests
* Update controllers and stop using the focus layout
* copy changes
* Update verification.ex
* Remove dead template
* Update settings_general.html.heex
* Update copy in tests
* Update installation.ex
* Remove dangling dot
* Fix link
* Update installation.ex
* Update installation.ex
* Better tooltips?
* Simpler labels
* Revert "Simpler labels"
This reverts commit 797560ef82f2067458b03b884be5aecc8fdc72bc.
* Add copy to clipboard link and fix snippet's dark mode
* Offer installation detection skip only if ws connected
* Put COPY link at the bottom with background
* Make tooltips link to docs
* Fix cherry-pick gone wrong
* Hide tooltips on mobile screens
* WIP: 404 tracking wizard
* Revert "WIP: 404 tracking wizard"
This reverts commit a9c9c79bbd.
* Update lib/plausible_web/live/components/verification.ex
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
* Update lib/plausible_web/live/installation.ex
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
* Use current_user from socket.assigns
* Update lib/plausible_web/live/installation.ex
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
* Use current_user from socket.assigns
* Use conn.private to steer verification tests
* Drop non-sticky tooltip in favour of component parametrization
Co-authored-by: Artur Pata <artur.pata@gmail.com>
* Reapply "WIP: 404 tracking wizard"
This reverts commit 3ba81671d7.
* Fix installation tests including 404 tracking
* Fixup the tooltip component
* Format
* Update installation.ex
* Put flash whenever installation option changes
* Use last known installation type on domain change
* Extract user flow definition to provide compile-time checks
* See if this helps running CE migrations successfully
* Use `styled_link` on registration/login views
* Don't crash when there's no conn.private carried over
* Format
* Push "Determining installation type" message a bit lower
* Use links and footer lists uniformly
This commit introduces a `<.focus_list/>` component
for rendering focus box footer links with colored
discs. It also equips generic link components
with the ability of sending non-GET requests
along with CSRF token, so we can apply uniform
styling and stop using legacy Phoenix link tags.
cc @zoldar @apata
* ws 👾
* Render more descriptive flashes on script config change
---------
Co-authored-by: Marko Saric <34340819+metmarkosaric@users.noreply.github.com>
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
Co-authored-by: Artur Pata <artur.pata@gmail.com>
* Set log_comment with request information
* CRMAuthPlug -> SuperAdminOnlyPlug
* Super basic debug view
* Handle clustered setups
* Changelog entry
* Cleanup
* fragment trick to use ecto querying, filtering
* Move clustered_table? function to IngestRepo module
* Format
* More resilient user_id getting in helper
* Add data migration for creating and syncing location_data table and dictionary
* Migration to populate location data
* Daily cron to refresh location dataset if changed
* Add support for visit:country_name, visit:region_name and visit:city_name dimensions
Under the hood this relies on a `location_data` table in clickhouse being regularly synced with
plausible/location repo and dictionary lookups used in ALIAS columns
* Update queue name
* Update documentation
* Explicit structs
* Improve docs further
* Migration comment
* Add queues
* Add error when already loaded
* Test for filtering by new dimensions
* Update deps
* dimension -> select_dimension
* Update a test
* populate site_imports from sites.imported_data in CE
* not dry_run?
* Wrap data migration using `with_repo` to ensure ClickhouseRepo is running
* Do not create funnels in seeds when running CE
* Remove migrator wrapper
* Explicitly raise on rollback attempt
* Put a warning in data migration scripts which are put in migrations
---------
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
* Remove references to `site.imported_data`
* Count pre-existing ID 0 imports when showing pageview count summary for legacy imports
* Fix tests after rebase
* Dry `delete_imported_stats!`
* Clean up remaining imported data references and add notes
* Ensure only complete imports are considered in site imports data migration
* Refactor `SiteImports` data migration for clarity (h/t @RobertJoonas)
* Fix tests
* Always select and clear import ID 0 when referring to legacy imports
* Implement script for adding site import entries and adjusting end dates
* Log cases where end date computation is using fallback
* Don't log queries when running the migration to reduce noise
* WIP mutation to populate event session columns
* Remove duplication
* report errors, allow_nondeterministic_updates
* use right columns
* Update existing columns instead of session_* ones
* Make dialyzer happy
* Fix issue with passing pre-existing params in
* Logger -> IO.puts
* Use IngestRepo.config for connection settings
* Make dictionary options configurable
* Move allow_nondeterministic_mutations to within the migration
* Solve credo warning about too deep nesting
* Missed logger call
* Pattern matching in function head
* Add data migration for moving to VersionedCollapsingMergeTree
This has been tested locally and partially on staging. Still requires a bit of work to verify.
Verification query:
```
SELECT main._partition_id, tmp.count, main.count
FROM (
SELECT _partition_id, count() AS count
FROM sessions_v2_tmp_versioned
GROUP BY _partition_id
) AS tmp
FULL OUTER JOIN (
SELECT _partition_id, count() AS count
FROM sessions_v2
GROUP BY _partition_id
) AS main
ON (tmp._partition_id == main._partition_id)
ORDER BY main._partition_id
```
* Add an early exit to migration
* cluster? extract common code