-
Notifications
You must be signed in to change notification settings - Fork 166
Allow the application to run without analytics #1802
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR introduces the ability to disable analytics functionality in the application by adding a new OPS_ANALYTICS_ENABLED environment variable that defaults to true. When set to false, analytics-related features are conditionally skipped.
- Adds
ANALYTICS_ENABLEDsystem property with a default value oftrue - Conditionally registers analytics routes, seeds, and UI components based on the flag
- Updates configuration files to include the new environment variable
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/server/shared/src/lib/system/system-prop.ts | Adds ANALYTICS_ENABLED enum value to AppSystemProp |
| packages/server/shared/src/lib/system/system.ts | Adds default value for ANALYTICS_ENABLED and implements isAnalyticsEnabled() helper |
| packages/server/shared/test/system/system.test.ts | Adds test coverage for the new isAnalyticsEnabled() function |
| packages/server/api/src/main.ts | Conditionally executes analytics seeding based on the enabled flag |
| packages/server/api/src/app/flags/flag.service.ts | Returns undefined for analytics public URL when analytics are disabled |
| packages/server/api/src/app/database/seeds/openops-analytics-seed.ts | Adds early return guard for disabled analytics |
| packages/server/api/src/app/authentication/authentication.controller.ts | Conditionally registers analytics routes only when enabled |
| packages/server/api/src/app/ai/mcp/tools-initializer.ts | Checks analytics enabled status before loading Superset tools |
| packages/server/api/src/app/ai/mcp/superset-tools.ts | Returns empty toolset when analytics are disabled |
| packages/server/api/test/unit/authentication/authentication.controller.test.ts | Adds tests verifying analytics routes are conditionally registered |
| packages/server/api/tsconfig.spec.json | Adds @fastify/cookie type declaration |
| packages/server/api/.env.tests | Sets OPS_ANALYTICS_ENABLED=true for test environment |
| packages/react-ui/src/app/router.tsx | Conditionally adds analytics route based on public URL flag |
| packages/react-ui/src/app/features/navigation/lib/menu-links-hook.ts | Conditionally includes analytics menu link when public URL is available |
| deploy/helm/openops/values.yaml | Adds OPS_ANALYTICS_ENABLED: "true" to Helm values |
| deploy/helm/openops/values.overrides-example.yaml | Includes example override for analytics enabled flag |
| deploy/docker-compose/.env.defaults | Sets default value for OPS_ANALYTICS_ENABLED |
| .env.template | Documents the new OPS_ANALYTICS_ENABLED environment variable |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
packages/server/api/test/unit/authentication/authentication.controller.test.ts
Show resolved
Hide resolved
|
@maor-rozenfeld I've opened a new pull request, #1803, to work on those changes. Once the pull request is ready, I'll request review from you. |
|
@maor-rozenfeld I've opened a new pull request, #1804, to work on those changes. Once the pull request is ready, I'll request review from you. |
The analytics test in `system.test.ts` modifies
`process.env['OPS_ANALYTICS_ENABLED']` but doesn't restore it, causing
potential test pollution.
## Additional Notes
Wrapped test assertions in try/finally block to guarantee cleanup even
on assertion failure. Maintains consistency with existing
`Reflect.deleteProperty` usage in the file's `beforeEach` hook.
```typescript
it('enables analytics by default and respects disabling flag', () => {
const originalAnalyticsEnabled = process.env['OPS_ANALYTICS_ENABLED'];
try {
expect(system.isAnalyticsEnabled()).toBe(true);
process.env['OPS_ANALYTICS_ENABLED'] = 'false';
expect(system.isAnalyticsEnabled()).toBe(false);
} finally {
if (originalAnalyticsEnabled === undefined) {
Reflect.deleteProperty(process.env, 'OPS_ANALYTICS_ENABLED');
} else {
process.env['OPS_ANALYTICS_ENABLED'] = originalAnalyticsEnabled;
}
}
});
```
## Testing Checklist
Check all that apply:
- [x] I tested the feature thoroughly, including edge cases
- [x] I verified all affected areas still work as expected
- [x] Automated tests were added/updated if necessary
- [x] Changes are backwards compatible with any existing data, otherwise
a migration script is provided
## Visual Changes (if applicable)
N/A
<!-- START COPILOT CODING AGENT TIPS -->
---
💡 You can make Copilot smarter by setting up custom instructions,
customizing its development environment and configuring Model Context
Protocol (MCP) servers. Learn more [Copilot coding agent
tips](https://gh.io/copilot-coding-agent-tips) in the docs.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: maor-rozenfeld <49363375+maor-rozenfeld@users.noreply.github.com>
…#1803) The test for analytics being disabled only verified that analytics GET routes were skipped, but didn't confirm that essential POST routes (`/sign-up`, `/sign-in`, `/sign-out`) remained functional. ## Changes Enhanced `skips analytics routes when analytics are disabled` test to verify: - Analytics GET routes are not registered (existing) - All three POST authentication routes are registered with correct paths, options, and handlers (new) ```typescript // Now verifies both what's disabled and what remains active expect(app.get).not.toHaveBeenCalled(); expect(app.post).toHaveBeenCalledTimes(3); const signUpRoute = app.post.mock.calls.find(([path]) => path === '/sign-up'); expect(signUpRoute).toBeDefined(); expect(signUpRoute?.[1]).toEqual(expect.any(Object)); expect(signUpRoute?.[2]).toEqual(expect.any(Function)); // Similar checks for /sign-in and /sign-out ``` ## Additional Notes Addresses review feedback from #1802 requesting verification that core authentication functionality remains intact when analytics is disabled. ## Testing Checklist - [x] I tested the feature thoroughly, including edge cases - [x] I verified all affected areas still work as expected - [x] Automated tests were added/updated if necessary - [x] Changes are backwards compatible with any existing data, otherwise a migration script is provided ## Visual Changes (if applicable) N/A - test-only changes <!-- START COPILOT CODING AGENT TIPS --> --- 💬 We'd love your input! Share your thoughts on Copilot coding agent in our [2 minute survey](https://gh.io/copilot-coding-agent-survey). --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: maor-rozenfeld <49363375+maor-rozenfeld@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
packages/server/api/test/unit/authentication/authentication.controller.test.ts:1
- The assertion checks index
[2]for the handler function, but based on the registration pattern in line 111 whereembedRoute?.[1]is checked for the/analytics-embed-idroute (which has no options object), the handler should be at index[1], not[2]. This index should match the pattern used for the embed route.
import { FastifyInstance } from 'fastify';
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| value: system.isAnalyticsEnabled() | ||
| ? system.get(AppSystemProp.ANALYTICS_PUBLIC_URL) | ||
| : undefined, |
Copilot
AI
Jan 6, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The conditional logic returns undefined when analytics is disabled, but system.get() already returns undefined when the value is not set. Consider simplifying to return system.get(AppSystemProp.ANALYTICS_PUBLIC_URL) ?? undefined when analytics is enabled, or verify if there's a scenario where the URL could be set but analytics disabled.
| const { data: analyticsPublicUrl } = flagsHooks.useFlag<string | undefined>( | ||
| FlagId.ANALYTICS_PUBLIC_URL, | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this leads to an issue if ANALYTICS_ENABLED=false but someone still leaves ANALYTICS_PUBLIC_URL in .env. Since you added ANALYTICS_ENABLED I would propose to also use it here and in the router file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what i mean it's not consistent as the check in the BE is different using the new var
packages/react-ui/src/app/router.tsx
Outdated
| FlagId.FEDERATED_LOGIN_ENABLED, | ||
| ); | ||
|
|
||
| const { data: analyticsPublicUrl } = flagsHooks.useFlag<string | undefined>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It slightly violates rule of hooks, it still works because createRoutes() is called directly inside the component, at the top level. It is consistent with the other flag checks above.
React Hook "useHasAnalyticsAccess" is called in function "createRoutes" that is neither a React function component nor a custom React Hook function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 40 out of 40 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /* eslint-disable @typescript-eslint/no-empty-function */ | ||
|
|
||
| export const analyticsAccessService = { | ||
| verifyUserAnalyticsAccess(_: string): void {}, |
Copilot
AI
Jan 9, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The parameter name '_' is not descriptive. Use a meaningful name like 'userId' or 'openopsUserId' to match the type definition in access-service-factory.ts.
| verifyUserAnalyticsAccess(_: string): void {}, | |
| verifyUserAnalyticsAccess(userId: string): void {}, |
# Conflicts: # packages/react-ui/src/app/features/navigation/lib/menu-links-hook.ts # packages/react-ui/src/app/router.tsx # packages/server/api/src/app/authentication/authentication.controller.ts
|



Resolves OPS-3284.