Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@hiteshshimpi-55
Copy link
Contributor

@hiteshshimpi-55 hiteshshimpi-55 commented Sep 27, 2025

Important

Refactor GetDetailedUsageAnalytics for improved performance and maintainability with parallel data fetching and reduced complexity.

  • Behavior:
    • Refactor GetDetailedUsageAnalytics in feature_usage_tracking.go for improved performance and maintainability.
    • Introduces parallel data fetching using goroutines for fetchCustomer, fetchSubscriptions, and fetchAnalytics.
    • Maintains existing API contract and business logic.
  • Architecture:
    • New AnalyticsData struct to consolidate data handling.
    • Simplifies function structure with validateAnalyticsRequest, fetchAnalyticsData, and buildAnalyticsResponse.
    • Implements single-pass data processing and reduces nesting levels.
  • Repository:
    • Removes unused functions from feature_usage.go and clickhouse/feature_usage.go.
    • Updates getStandardAnalytics and getMaxBucketAnalytics for improved query handling.
  • Testing:
    • Comprehensive unit and integration tests to ensure no regression.
    • Performance tests to validate improvements.

This description was created by Ellipsis for 3356663. You can customize this summary. It will automatically update as commits are pushed.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

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

Caution

Changes requested ❌

Reviewed everything up to 958ae51 in 1 minute and 54 seconds. Click for details.
  • Reviewed 1609 lines of code in 4 files
  • Skipped 0 files when reviewing.
  • Skipped posting 9 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with πŸ‘ or πŸ‘Ž to teach Ellipsis.
1. docs/prds/refactor-analytics-function.md:1
  • Draft comment:
    Excellent, detailed PRD document. Consider adding any migration or rollout notes if applicable.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 30% None
2. internal/domain/events/feature_usage.go:5
  • Draft comment:
    Removal of the shopspring/decimal import is acceptable if the domain layer no longer exposes implementation details.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 30% None
3. internal/repository/clickhouse/feature_usage.go:472
  • Draft comment:
    The grouping logic in getStandardAnalytics looks well-structuredβ€”ensuring 'feature_id' is always included. Double‐check that the ordering of scan targets matches the SQL alias order.
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 0% <= threshold 30% The comment starts with a purely informative statement about the grouping logic, which is not allowed. The second part of the comment asks the author to double-check the ordering of scan targets, which is also not allowed. Therefore, this comment should be removed.
4. internal/repository/clickhouse/feature_usage.go:1547
  • Draft comment:
    Consider injecting the FeatureService instead of instantiating it inline here. This follows dependency injection best practices.
  • Reason this comment was not posted:
    Comment was not on a location in the diff, so it can't be submitted as a review comment.
5. internal/service/feature_usage_tracking.go:1066
  • Draft comment:
    Ensure that dependencies like CustomerRepo and FeatureRepo are injected via ServiceParams or defined in the service struct to avoid nil dereferences at runtime.
  • Reason this comment was not posted:
    Comment was on unchanged code.
6. internal/service/feature_usage_tracking.go:1272
  • Draft comment:
    The enrichment of analytics with feature and meter data is clear. Ensure thorough testing for edge cases, especially for cases when points are empty or data is partially available.
  • Reason this comment was not posted:
    Confidence changes required: 30% <= threshold 30% None
7. internal/service/feature_usage_tracking.go:1520
  • Draft comment:
    MergeTimeSeriesPoints correctly aggregates points by timestamp. Review the usage of pointers in the loop to ensure there's no unintended aliasing.
  • Reason this comment was not posted:
    Confidence changes required: 30% <= threshold 30% None
8. internal/service/feature_usage_tracking.go:2183
  • Draft comment:
    The weighted sum aggregation formula appears reasonable; ensure that period calculations and remaining seconds are unit-tested to handle edge cases.
  • Reason this comment was not posted:
    Confidence changes required: 30% <= threshold 30% None
9. internal/service/feature_usage_tracking.go:2230
  • Draft comment:
    Overall, the refactoring into smaller helper functions improves readability. Consider addressing remaining TODOs and refining log messages for production readiness.
  • Reason this comment was not posted:
    Confidence changes required: 30% <= threshold 30% None

Workflow ID: wflow_CtmTyOZN5wEhXnCt

You can customize Ellipsis by changing your verbosity settings, reacting with πŸ‘ or πŸ‘Ž, replying to comments, or adding code review rules.

@hiteshshimpi-55
Copy link
Contributor Author

@ellipsis-dev can you review ?

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

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

Caution

Changes requested ❌

Reviewed everything up to 3356663 in 1 minute and 49 seconds. Click for details.
  • Reviewed 1655 lines of code in 4 files
  • Skipped 0 files when reviewing.
  • Skipped posting 2 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with πŸ‘ or πŸ‘Ž to teach Ellipsis.
1. internal/service/feature_usage_tracking.go:950
  • Draft comment:
    GetDetailedUsageAnalytics is now broken into smaller helper functions (validateAnalyticsRequest, fetchAnalyticsData, buildAnalyticsResponse), which improves maintainability and readability. Ensure that any changes here keep the API contract unchanged.
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 0% <= threshold 30% The comment is purely informative, describing the refactoring changes made to the GetDetailedUsageAnalytics function. It does not provide any actionable feedback or specific suggestions for improvement. It also asks to ensure the API contract is unchanged, which is against the rules.
2. internal/service/feature_usage_tracking.go:1158
  • Draft comment:
    The analytics enrichment logic (enrichWithMetadata, calculateCosts, aggregateAnalyticsByGrouping) has been modularized well. Verify that the cost calculation, grouping, and metadata enrichment continue to match existing business logic.
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 0% <= threshold 30% This comment is asking the PR author to verify that the cost calculation, grouping, and metadata enrichment continue to match existing business logic. This falls under asking the author to ensure behavior is intended, which is against the rules. Therefore, this comment should be removed.

Workflow ID: wflow_vEy0X6qKe3jLONjR

You can customize Ellipsis by changing your verbosity settings, reacting with πŸ‘ or πŸ‘Ž, replying to comments, or adding code review rules.

@hiteshshimpi-55
Copy link
Contributor Author

@coderabbitai can you review ?

@coderabbitai
Copy link

coderabbitai bot commented Sep 30, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash

# Get PR details
echo "=== PR Details ==="
gh pr view 587 --json title,body,author,labels,additions,deletions,changedFiles,files

# Get the diff
echo -e "\n=== PR Diff ==="
gh pr diff 587

Length of output: 62994


@hiteshshimpi-55, I'll review this PR for you. This is a substantial refactoring of the analytics function. Let me analyze the changes in detail.

🎯 Overview

This PR refactors GetDetailedUsageAnalytics to improve performance and maintainability. The changes look well-structured overall, but I've identified several important issues that need attention.

πŸ”΄ Critical Issues

1. Broken Parallel Fetching Logic

Location: internal/service/feature_usage_tracking.go (Lines 982-1032)

The fetchAnalyticsData function has a critical flaw in its parallel execution:

go func() {
    // Wait for customer first
    customer := <-customerChan  // ⚠️ DEADLOCK: reads before customer goroutine completes
    subscriptions, err := s.fetchSubscriptions(ctx, customer.ID)
    // ...
}()

Problem: The subscription goroutine reads from customerChan while the customer goroutine tries to write to it, but the main select loop also tries to read from the same channel. This creates a race condition and potential deadlock.

Fix: Remove the "parallel" approach here since subscriptions depend on customer data:

func (s *featureUsageTrackingService) fetchAnalyticsData(ctx context.Context, req *dto.GetUsageAnalyticsRequest) (*AnalyticsData, error) {
    // 1. Fetch customer first (required for subscriptions)
    customer, err := s.fetchCustomer(ctx, req.ExternalCustomerID)
    if err != nil {
        return nil, err
    }

    // 2. Fetch subscriptions and analytics in parallel
    var wg sync.WaitGroup
    var subscriptions []*subscription.Subscription
    var analytics []*events.DetailedUsageAnalytic
    var subErr, analyticsErr error

    wg.Add(2)
    
    go func() {
        defer wg.Done()
        subscriptions, subErr = s.fetchSubscriptions(ctx, customer.ID)
    }()
    
    go func() {
        defer wg.Done()
        params := s.createAnalyticsParams(ctx, req)
        params.CustomerID = customer.ID
        analytics, analyticsErr = s.fetchAnalytics(ctx, params)
    }()
    
    wg.Wait()
    
    if subErr != nil {
        return nil, subErr
    }
    if analyticsErr != nil {
        return nil, analyticsErr
    }

    // Rest of the function...
}

2. GROUP BY Logic Change May Break Queries

Location: internal/repository/clickhouse/feature_usage.go (Lines 475-478)

// Always include feature_id for cost calculation, then add requested grouping dimensions
groupByColumns := []string{"feature_id"}
groupByColumnAliases := []string{"feature_id"}

Problem: The code now always includes feature_id in GROUP BY, even when users don't request it. This fundamentally changes query behavior:

  • When grouping by source alone, users now get (feature_id, source) combinations instead of source-level aggregates
  • This breaks backward compatibility

Impact:

  • Query results will be more granular than expected
  • Aggregate values will be split across features unexpectedly

Recommendation: Either:

  1. Remove the forced feature_id grouping and handle cost calculation differently
  2. Document this as a breaking change
  3. Add the aggregation layer mentioned in aggregateAnalyticsByGrouping (but verify it's actually called)

3. Aggregation Function Not Integrated

Location: internal/service/feature_usage_tracking.go (Lines 1059-1061)

// Aggregate results by requested grouping dimensions
analytics := s.aggregateAnalyticsByGrouping(data.Analytics, data.Params.GroupBy)

This function is meant to fix issue #2 above, but:

  • It's only called in buildAnalyticsResponse for standard analytics
  • Max bucket analytics bypass this aggregation
  • The aggregation is done in-memory after fetching detailed data (inefficient)

Recommendation: Fix the SQL queries instead of post-processing.

⚠️ High Priority Issues

4. Duplicate Functions

Location: internal/service/feature_usage_tracking.go

You have two nearly identical functions:

  • enrichAnalyticsWithFeatureMeterAndPriceData (Line 1581)
  • enrichAnalyticsWithFeatureMeterAndPriceDataAndMaxBuckets (Line 1581)

The second one appears to be dead code. Clean this up.

5. Missing Error Context

Location: Multiple locations in feature_usage_tracking.go

When errors occur during enrichment or cost calculation, you log warnings but continue:

if err := s.enrichWithMetadata(ctx, data); err != nil {
    s.Logger.Warnw("failed to enrich analytics with metadata",
        "error", err,
        "analytics_count", len(analytics),
    )
    // Continue with partial data rather than failing completely
}

Problem: Users get incomplete data without knowing it. Consider:

  • Adding a field to the response indicating partial data
  • Or returning errors for critical failures

6. Incorrect Scan Arguments

Location: internal/repository/clickhouse/feature_usage.go (Lines 856-878)

The max bucket totals scanning logic looks fragile:

totalSelectColumns := len(selectColumns) + 2
scanTargets := make([]interface{}, totalSelectColumns)

This assumes a specific order but doesn't validate it. If the SELECT clause changes, scans will fail silently with wrong data in wrong fields.

πŸ’‘ Suggestions

7. PRD Document in Codebase

The 403-line PRD in docs/prds/ is excellent documentation but might be better suited for:

  • Confluence/Notion
  • GitHub wiki
  • Separate docs repository

This keeps the codebase focused on code.

8. Missing Tests

The PR description mentions "comprehensive unit and integration tests" but I don't see any test file changes. Were tests added in a separate commit?

9. Performance Claims Need Validation

The PRD claims "3x performance improvement" but there's no benchmark data in the PR. Consider adding:

  • Benchmark tests
  • Performance comparison results

πŸ“‹ Minor Issues

10. Unused Import

import (
    "strings"  // Added but may not be used everywhere
)

11. Magic Numbers

expectedColumns := totalGroupByColumns + 5 // +5 for sum_usage, max_usage...

Consider using constants for these magic numbers.

βœ… What Looks Good

  1. Cleaner separation of concerns - Functions have single responsibilities
  2. Better error handling - More descriptive errors with context
  3. Removed dead code - Cleaned up unused repository methods
  4. Comprehensive PRD - Well-documented requirements

🎬 Recommendations

Before merging:

  1. βœ… Fix the parallel fetching deadlock (Critical)
  2. βœ… Fix or document the GROUP BY behavior change (Critical)
  3. βœ… Remove duplicate enrichment function
  4. βœ… Add tests demonstrating no regression
  5. βœ… Add benchmark tests validating performance claims
  6. βœ… Consider moving PRD to external docs

Nice to have:

  1. Add response field for partial data indicator
  2. Extract magic numbers to constants
  3. Add validation for scan target alignment

Would you like me to help generate test cases or create issues for any of these findings?

@hiteshshimpi-55 hiteshshimpi-55 merged commit 6b1f4bd into flexprice:develop Sep 30, 2025
2 checks passed
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.

1 participant