Repository navigation
feat: let admins switch download analytics on from the settings page - #2340
Merged
Merged
Conversation
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Analytics visibility can remain stale or incorrect, and contribution filtering permits conflicting settings controls.
3 open findings
What changed in this PR
Adds an admin-controlled download analytics switch, allowing registries to backfill history before exposing charts and analytics endpoints.
Changes:
- Adds runtime analytics visibility settings and endpoint gating.
- Adds the dashboard switch and extensible settings sections.
- Updates API models, tests, and changelogs.
| File | Description |
|---|---|
| webui/test/unit/pages/admin-dashboard/settings.spec.tsx | Tests analytics saves and contributed switches. |
| webui/src/pages/admin-dashboard/use-settings.ts | Seeds analytics into public settings cache. |
| webui/src/pages/admin-dashboard/settings.tsx | Renders configurable settings sections. |
| webui/src/pages/admin-dashboard/settings-sections.ts | Defines built-in and contributed sections. |
| webui/src/pages/admin-dashboard/settings-max-size-item.tsx | Extracts the size-limit control. |
| webui/src/page-settings.ts | Adds section contribution configuration. |
| webui/src/index.ts | Exports contribution types. |
| webui/src/extension-registry-types.ts | Adds analytics settings fields. |
| webui/CHANGELOG.md | Documents dashboard additions. |
| server/src/test/java/org/eclipse/openvsx/UserAPITest.java | Updates registry service wiring. |
| server/src/test/java/org/eclipse/openvsx/settings/SettingsJsonMapperTest.java | Tests analytics field mapping. |
| server/src/test/java/org/eclipse/openvsx/settings/SettingsAPITest.java | Tests public analytics serialization. |
| server/src/test/java/org/eclipse/openvsx/settings/DownloadAnalyticsVisibilityServiceTest.java | Tests effective visibility. |
| server/src/test/java/org/eclipse/openvsx/settings/DownloadAnalyticsSettingTest.java | Tests storage, validation, and publication. |
| server/src/test/java/org/eclipse/openvsx/RegistryAPITest.java | Updates registry service wiring. |
| server/src/test/java/org/eclipse/openvsx/LocalRegistryServiceTest.java | Tests reported analytics availability. |
| server/src/test/java/org/eclipse/openvsx/analytics/DownloadAnalyticsEndpointTest.java | Enables analytics during endpoint tests. |
| server/src/test/java/org/eclipse/openvsx/analytics/DownloadAnalyticsAPITest.java | Tests disabled analytics returning 404. |
| server/src/test/java/org/eclipse/openvsx/admin/AdminAPITest.java | Updates registry service wiring. |
| server/src/main/java/org/eclipse/openvsx/settings/SettingsJsonMapper.java | Maps analytics settings fields. |
| server/src/main/java/org/eclipse/openvsx/settings/DownloadAnalyticsVisibilityService.java | Combines configuration and runtime visibility. |
| server/src/main/java/org/eclipse/openvsx/settings/DownloadAnalyticsSetting.java | Implements the persisted analytics switch. |
| server/src/main/java/org/eclipse/openvsx/LocalRegistryService.java | Reports effective analytics availability. |
| server/src/main/java/org/eclipse/openvsx/json/SiteSettingsJson.java | Exposes public analytics visibility. |
| server/src/main/java/org/eclipse/openvsx/json/SettingsJson.java | Adds the admin analytics field. |
| server/src/main/java/org/eclipse/openvsx/json/RegistryVersionJson.java | Clarifies availability documentation. |
| server/src/main/java/org/eclipse/openvsx/analytics/DownloadAnalyticsAPI.java | Gates requests on runtime visibility. |
| server/CHANGELOG.md | Documents admin-controlled analytics. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
netomi
force-pushed
the
gnugomez/main/extension-analytics-setting
branch
from
October 16, 2026 07:11
76c8be4 to
a49ac9c
Compare
The site settings carry whether download analytics is shown and follow the admin switch live, so the flag on /api/version has no reader left. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The switch decides whether the web UI shows download analytics, not whether analytics is collected, which ovsx.analytics.enabled controls. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The visibility switch only decides what the web UI shows. The endpoint serves data wherever analytics is configured, so it can be read while a registry backfills its history before showing it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…analytics tests A contributed section whose switches were all dropped as duplicates rendered a bare heading. The weekly downloads test for a hidden card asserted before the site settings loaded, so it passed even with the check removed. Document that contributed switches share the built-in section's availability. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributed sections are placed among the built-in ones alphabetically instead of after them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The endpoint is public, and a caller-chosen from/to/interval let anyone request arbitrary windows, each a cache miss on the server and a distinct URL for HTTP caches. The only consumer, the weekly downloads card, always asks for the last 52 weeks of days, so the server now fixes that window and ignores query parameters. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…onfigured downloadAnalyticsVisible is absent from GET /admin/settings where download analytics is not configured, which replaces the separate read-only downloadAnalyticsConfigured field. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The controllers had to pair the service with SettingsJsonMapper in both directions. The service now returns SettingsJson and SiteSettingsJson and takes a SettingsJson update, like the other services do, and the mapper becomes a package-private detail of it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…elogs DownloadAnalyticsSetting.isVisible() lost its last callers, so it and the store it read go. Cover the effective analytics switch through SettingsService and a contributed section hiding itself, split a test whose assertion read like a bug, and shorten the changelog entries to their final state. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SettingsJson carried a fixed set of fields, so a WritableSetting added by a deployment's own module never reached /admin/settings and a switch contributed through adminSettingsSections could not be saved. Rows of such settings now travel as camelCase properties named after their row keys, on the public settings too when the setting is a PublicSetting. Built-in settings stay writable only through their own properties. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Download analytics shows a weekly downloads card on every extension page as soon as
ovsx.analytics.enabledis set. A registry that has just turned analytics on usually wants to backfill its download history first, so the card would show incomplete data in the meantime. This adds a runtime setting that decides whether the web UI shows the card, switched by an admin on the Settings page, and lets a deployment add runtime settings of its own to that page.Server
DownloadAnalyticsSetting, stored underdownload-analytics-visible, off by default. Switching it on is refused where analytics is not configured.GET /admin/settingsreturns the stored switch asdownloadAnalyticsVisible, and leaves it out where analytics is not configured (ovsx.analytics.enabled). In an update, as for every setting, an absent field leaves it unchanged.downloadAnalyticsVisible = configured && switched on, so a switch left on after analytics was unconfigured reads as off.GET /api/{namespace}/{extension}/analytics/downloadsnow always returns the daily downloads of the last 52 weeks, ending today, and ignores query parameters. A public endpoint with a caller-chosenfrom/to/intervallet anyone request arbitrary windows, up to five years each, every one a miss in the settled-range cache and a distinct URL for HTTP caches. With one window per extension, the work per request is bounded, the settled-range cache holds one entry per extension and day (refreshed after its TTL,ovsx.analytics.settled-cache.ttl, one hour by default), and the 10-minute publicCache-Controlworks at CDNs for the plain URL. Appending an arbitrary query string still bypasses a CDN; it no longer changes what the server computes.analyticsEnabledis removed from/api/version. It was added in feat: time-series download analytics #2134 and is unreleased; the site settings carry the same information and follow the switch live.SettingsServicereturnsSettingsJsonandSiteSettingsJsonand takes aSettingsJsonupdate, like the other services, soAdminAPIandSettingsAPIno longer pair it withSettingsJsonMapper. The mapper is now a package-private detail of the service.SettingsJsonandSiteSettingsJsoncarry them as additional top-level properties (@JsonAnyGetter/@JsonAnySetter), named in camelCase after the row key: a setting stored underaudit-log-enabledisauditLogEnabledon the wire. Safety is unchanged: the service only writes rows a registered setting claims, so an unknown property is ignored; every value goes through its setting'svalidate; built-in settings are writable only through their own properties, never under another spelling; and only aPublicSetting's own view reaches/api/-/settings.Web UI
SiteSettings.downloadAnalyticsVisible. An admin's save seeds the public settings and they poll, so a switch flipped during a session reaches the card without a reload.getExtensionDownloadSeriestakes only the namespace and name, since the server fixes the window. The unreleasedDownloadSeriesIntervaltype is removed.PageSettings.elements.adminSettingsSections. Additive only: a switch over a key the page already uses is ignored, a section left without switches is omitted, and switches added to a built-in section share its availability.settings-max-size-item.tsx.Adding a setting in a deployment
A deployment that builds on the registry, such as openvsx-ef, needs two pieces and no changes upstream.
1. Server: a
WritableSettingbean in the deployment's own package, picked up by its component scan. The row key is kebab-case; the property on the wire is its camelCase form.The value is stored, cached per node and propagated across the cluster like the built-in settings, and a save publishes
SettingsChangedEvent. Server code that needs the value at runtime can readSettingsService.getCurrentSettings().getAdditionalSettings().get("registryAnalyticsPublic"), which comes from the cached snapshot.2. Web UI: an
adminSettingsSectionsentry in the deployment'sPageSettings, keyed by the camelCase property:A switch appended to the built-in
analyticssection is shown only where download analytics is configured; a section of its own can hide itself withavailable. If the setting is public, a visitor-facing page reads it throughuseSiteSettings().SiteSettingsonly types the built-in properties, so a deployment's own property is read as(useSiteSettings().data as Record<string, unknown> | undefined)?.registryAnalyticsPublic === true.Upgrade note
Registries already running with
ovsx.analytics.enabled=truestop showing the weekly downloads card until an admin switches it on.Test plan
DownloadAnalyticsAPITest(fixed window, query parameters ignored),DownloadAnalyticsSettingTest,SettingsJsonMapperTest(additional properties both ways, the built-in guard, the flat wire shape),SettingsServiceTest(the effective analytics switch, and a deployment-style setting read, updated and published through the JSON documents),SettingsAPITest,AdminAPITest,LocalRegistryServiceTest; the full suite passes apart from the Testcontainers testsyarn lint,yarn tsc,yarn test(536 tests), including the Settings page and weekly downloads specsDownloadAnalyticsEndpointTest,DownloadAnalyticsDisabledTest) left to CI