Skip to content

feat: add metrics infrustructure to ui #2698

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

Merged
merged 5 commits into from
Aug 14, 2025
Merged

feat: add metrics infrustructure to ui #2698

merged 5 commits into from
Aug 14, 2025

Conversation

sareyu
Copy link
Collaborator

@sareyu sareyu commented Aug 11, 2025

Added wrapper for yaMetrica instance. Suppose yametrica will be initiated before app starts (it's part of core's renderLayout2 method) so there's no need for event queueing.

Call:

import {getMetrica} from 'utils/yaMetrica';
...
getMetrica('ui').reachGoal(...)

CI Results

Test Status: ⚠️ FLAKY

📊 Full Report

Total Passed Failed Flaky Skipped
358 352 0 4 2
Test Changes Summary ⏭️2

⏭️ Skipped Tests (2)

  1. Scroll to row, get shareable link, navigate to URL and verify row is scrolled into view (tenant/diagnostics/tabs/queries.test.ts)
  2. Copy result button copies to clipboard (tenant/queryEditor/queryEditor.test.ts)

Bundle Size: ✅

Current: 85.33 MB | Main: 85.33 MB
Diff: 0.00 KB (0.00%)

✅ Bundle size unchanged.

ℹ️ CI Information
  • Test recordings for failed tests are available in the full report.
  • Bundle size is measured for the entire 'dist' directory.
  • 📊 indicates links to detailed reports.
  • 🔺 indicates increase, 🔽 decrease, and ✅ no change in bundle size.

@sareyu sareyu linked an issue Aug 11, 2025 that may be closed by this pull request
@sareyu sareyu marked this pull request as draft August 11, 2025 14:56
@sareyu sareyu marked this pull request as ready for review August 11, 2025 16:40
@astandrik astandrik requested a review from Copilot August 12, 2025 15:03
@astandrik
Copy link
Collaborator

bugbot run

Copy link
Contributor

@Copilot Copilot AI left a 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 adds metrics infrastructure to the UI by implementing a wrapper for Yandex.Metrica counters. The implementation provides a consistent interface for tracking analytics events while gracefully handling cases where Metrica is not available.

Key changes:

  • Creates a wrapper utility for accessing Yandex.Metrica instances with fallback handling
  • Extends the UIFactory interface to include metrics configuration
  • Implements a fake counter class for development/testing environments

Reviewed Changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/utils/yaMetrica.ts Implements the core metrics wrapper with Counter interface, FakeMetrica fallback class, and getMetrica function
src/uiFactory/types.ts Adds yaMetricaMap property to UIFactory interface for metrics configuration


private warnOnce() {
if (!this.warnShown) {
console.warn(`YaMetrica counter "${this.name}" is not defined\n`);
Copy link
Preview

Copilot AI Aug 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The term 'YaMetrica' should be 'YandexMetrica' or 'Yandex.Metrica' for consistency with the official product name.

Suggested change
console.warn(`YaMetrica counter "${this.name}" is not defined\n`);
console.warn(`Yandex.Metrica counter "${this.name}" is not defined\n`);

Copilot uses AI. Check for mistakes.

Comment on lines 2 to 6

export interface Counter {
hit: (...args: unknown[]) => void;
params: (...args: unknown[]) => void;
userParams: (...args: unknown[]) => void;
Copy link
Preview

Copilot AI Aug 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Counter interface and its methods lack documentation. Consider adding JSDoc comments to explain the purpose of each method and their parameters.

Suggested change
export interface Counter {
hit: (...args: unknown[]) => void;
params: (...args: unknown[]) => void;
userParams: (...args: unknown[]) => void;
/**
* Represents a Yandex.Metrica counter interface for tracking analytics events.
*/
export interface Counter {
/**
* Sends a page hit event to the counter.
* @param args - Arguments for the hit event (varies by implementation).
*/
hit: (...args: unknown[]) => void;
/**
* Sets custom parameters for the counter.
* @param args - Arguments for setting parameters (varies by implementation).
*/
params: (...args: unknown[]) => void;
/**
* Sets user-specific parameters for the counter.
* @param args - Arguments for setting user parameters (varies by implementation).
*/
userParams: (...args: unknown[]) => void;
/**
* Sends a goal achievement event to the counter.
* @param args - Arguments for the goal event (varies by implementation).
*/

Copilot uses AI. Check for mistakes.

}
}
}

Copy link
Preview

Copilot AI Aug 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The getMetrica function lacks documentation. Consider adding JSDoc to explain its purpose, parameters, and return value, especially the fallback behavior to FakeMetrica.

Suggested change
/**
* Retrieves a YaMetrica counter instance by name.
*
* @param {string} name - The name of the YaMetrica counter to retrieve.
* @returns {Counter} The YaMetrica counter instance if found, otherwise a FakeMetrica instance.
* If the counter is not defined, FakeMetrica will log a warning once when its methods are called.
*/

Copilot uses AI. Check for mistakes.

const yaMetricaId = yaMetricaMap?.[name];
const metricaInstance = yaMetricaId
? (window[`yaCounter${yaMetricaId}`] as Counter)
: undefined;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Metrica ID Check Fails on Zero

The getMetrica function's truthiness check on yaMetricaId (e.g., yaMetricaId ? ...) incorrectly treats 0 as falsy. Since 0 is a valid Yandex Metrica counter ID, this causes the function to return a FakeMetrica instance instead of the real window['yaCounter0']. The condition should use yaMetricaId !== undefined or yaMetricaId != null to correctly identify valid IDs.

Fix in Cursor Fix in Web

@astandrik
Copy link
Collaborator

/claude_review

Copy link

claude bot commented Aug 12, 2025

Claude finished @astandrik's task —— View job


Code Review: Metrics Infrastructure Implementation

Review Tasks

  • Read and analyze the changed files
  • Check TypeScript type safety and interface conventions
  • Verify API patterns and window.api usage
  • Check for hardcoded strings (i18n compliance)
  • Review performance and security considerations
  • Analyze the counter ID 0 bug
  • Provide comprehensive review feedback

Summary

The implementation adds a clean wrapper for Yandex.Metrica integration with good fallback handling. However, there are several issues that need to be addressed to meet YDB Embedded UI standards.

Critical Issues

  1. 🐛 Bug: Counter ID 0 Handling (src/utils/yaMetrica.ts:47)
    • The truthiness check yaMetricaId ? ... incorrectly treats 0 as falsy
    • Since 0 is a valid Yandex.Metrica counter ID, this will return FakeMetrica instead of the real counter
    • Fix: Use yaMetricaId !== undefined or yaMetricaId != null
// Current (buggy)
const metricaInstance = yaMetricaId
    ? (window[`yaCounter${yaMetricaId}`] as Counter)
    : undefined;

// Should be
const metricaInstance = yaMetricaId !== undefined
    ? (window[`yaCounter${yaMetricaId}`] as Counter)
    : undefined;
  1. 📝 TypeScript Interface Naming Convention
    • The Counter interface (src/utils/yaMetrica.ts:3) doesn't follow the project's 'T' prefix convention
    • Per CLAUDE.md: "API Types: Prefixed with 'T' (e.g., TTenantInfo, TClusterInfo)"
    • Fix: Rename to TCounter for consistency

Code Quality Issues

  1. 📚 Missing Documentation (src/utils/yaMetrica.ts:3-8, 44-52)

    • The Counter interface and getMetrica function lack JSDoc comments
    • This is important for developer understanding, especially for the fallback behavior
  2. 🔤 Hardcoded String (src/utils/yaMetrica.ts:39)

    • The warning message contains a hardcoded string, violating i18n requirements
    • Per CLAUDE.md: "NEVER hardcode user-facing strings - use i18n"
    • While console warnings might be an exception, consider if this needs localization
  3. 🎯 Product Name Consistency (src/utils/yaMetrica.ts:39)

    • Should use "Yandex.Metrica" instead of "YaMetrica" for official product naming

Positive Aspects

Good patterns observed:

  • Clean fallback mechanism with FakeMetrica class
  • Single warning pattern prevents console spam
  • Proper TypeScript typing throughout
  • No direct API calls (follows window.api pattern)
  • No state mutations
  • Good error handling with graceful degradation

Recommendations

  1. Add comprehensive JSDoc documentation for public APIs
  2. Consider adding unit tests for the getMetrica function, especially edge cases (undefined map, ID 0, missing counter)
  3. Consider type-narrowing the unknown[] parameters in the Counter interface if possible
  4. Add an example usage comment in the file header to match the PR description

Example Fix for Critical Bug

export function getMetrica(name: string): Counter {
    const yaMetricaId = yaMetricaMap?.[name];
    const metricaInstance = yaMetricaId !== undefined
        ? (window[`yaCounter${yaMetricaId}`] as Counter)
        : undefined;

    return metricaInstance ?? new FakeMetrica(name);
}

The implementation is well-structured but needs these fixes to meet the project's standards and avoid the counter ID 0 bug.

@sareyu sareyu added this pull request to the merge queue Aug 14, 2025
Merged via the queue into main with commit e229c75 Aug 14, 2025
7 checks passed
@sareyu sareyu deleted the issue-2185-2 branch August 14, 2025 08:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

feat: add metrics infrustructure to ui
3 participants