Skip to content

feat(dashboards): wire focus filter across all marketing impact tabs#800

Merged
mrautela365 merged 5 commits into
mainfrom
feat/LFXV2-1972-focus-filter-wiring
May 28, 2026
Merged

feat(dashboards): wire focus filter across all marketing impact tabs#800
mrautela365 merged 5 commits into
mainfrom
feat/LFXV2-1972-focus-filter-wiring

Conversation

@mrautela365
Copy link
Copy Markdown
Contributor

@mrautela365 mrautela365 commented May 27, 2026

Summary

  • Update MarketingImpactFocusProgram type and FOCUS_TO_CLASSIFICATION mapping to match new Snowflake LF_SUB_DOMAIN_CLASSIFICATION values: LF Corporate, LF Events, LF Training, LFX Platform, Project Websites
  • Add classification query param support to getSocialReach, getBrandReach, getRevenueImpact, and getMarketingAttribution (service → controller → Snowflake SQL)
  • Wire Attribution and Performance Marketing tabs with combineLatest([slug$, focus$]) to re-fetch on focus change; pass classification to getRevenueImpact and getBrandReach in Overview tab
  • Remove "not yet available at program level" info banners from Attribution and Performance Marketing templates
  • Apply classification filter selectively — only to Snowflake tables that have the column (PIPELINE_SUMMARY does not; all other models including PAID_SOCIAL_REACH_BY_PROJECT_MONTH now support it)

Context

Follows 7 data-side PRs (merged May 18–26) that added LF_SUB_DOMAIN_CLASSIFICATION to 5 Platinum Snowflake models. This PR completes the UI wiring so the Focus filter works across all Marketing Impact dashboard tabs.

Test plan

  • Select a foundation (e.g., TLF) on the Marketing Impact dashboard
  • Click each focus pill (LF Corporate, LF Events, LF Training, LFX Platform, Project Websites) and verify data updates on Overview, Attribution, Performance Marketing, Email, and Web Activity tabs
  • Switch back to "All programs" and confirm unfiltered data displays
  • Verify no "not yet available" banners appear on Attribution or Performance Marketing tabs
  • Confirm Social Accounts and Social Listening tabs still render (unaffected by classification)

LFXV2-1972

🤖 Generated with Claude Code

@mrautela365 mrautela365 requested a review from a team as a code owner May 27, 2026 20:33
Copilot AI review requested due to automatic review settings May 27, 2026 20:33
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 27, 2026

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Threads focus-derived classification into marketing analytics: updates focus program types/mapping, frontend components to derive/pass classification, controller validation, and ProjectService SQL filters; removes program-level “not yet available” UI banners.

Changes

Marketing Focus Program Classification Filtering

Layer / File(s) Summary
Focus program type and classification mapping
packages/shared/src/interfaces/marketing-impact.interface.ts, packages/shared/src/constants/marketing-impact.constants.ts
MarketingImpactFocusProgram type and FOCUS_TO_CLASSIFICATION mapping updated to new focus program identifiers (lfCorporate, lfEvents, lfTraining, lfxPlatform, projectWebsites) and their Snowflake classification strings.
Frontend component classification integration
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/*
Attribution, Performance Marketing, and Overview tab components combine slug and focusProgram observables, derive classification via FOCUS_TO_CLASSIFICATION, pass classification to analytics service calls, and remove conditional “program-level not yet available” banners from templates.
Client analytics service: query param helper & signatures
apps/lfx-one/src/app/shared/services/analytics.service.ts
Introduces buildFoundationParams(foundationSlug, classification?) and updates getWebActivitiesSummary, getSocialReach, getBrandReach, getRevenueImpact, getEmailCtr, and getMarketingAttribution to accept an optional classification and include it in HTTP query params when provided.
Backend controller classification parameter handling
apps/lfx-one/src/server/controllers/analytics.controller.ts
Analytics endpoints use getValidatedClassification(req, operation) to validate optional classification, forward it to projectService methods, and conditionally include it in success logs.
Validation helper for classification query
apps/lfx-one/src/server/helpers/validation.helper.ts
Adds getValidatedClassification(req, operation) which reads classification from query, validates against VALID_CLASSIFICATIONS, and returns the validated value or undefined.
ProjectService: SQL classification filtering
apps/lfx-one/src/server/services/project.service.ts
ProjectService methods accept optional classification and conditionally inject LF_SUB_DOMAIN_CLASSIFICATION = ? filters into Snowflake SQL and adjust bind arrays for umbrella vs non-umbrella modes across social reach, attribution, brand reach (web portion), and revenue-impact queries.

Sequence Diagram(s)

sequenceDiagram
  participant UI as Marketing UI Component
  participant Rx as RxJS combineLatest
  participant ClientService as AnalyticsService (client)
  participant Server as AnalyticsController
  participant Project as ProjectService
  participant Snowflake

  UI->>Rx: subscribe(slug$, focusProgram$)
  Rx->>Rx: derive classification via FOCUS_TO_CLASSIFICATION
  Rx->>ClientService: call get*(slug, classification)
  ClientService->>Server: HTTP GET /analytics?foundationSlug=...&classification=...
  Server->>Project: projectService.get*(foundationSlug, classification)
  Project->>Snowflake: execute SQL with LF_SUB_DOMAIN_CLASSIFICATION bind
  Snowflake-->>Project: results
  Project-->>Server: aggregated results
  Server-->>ClientService: JSON response
  ClientService-->>UI: resolved data
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

ai-assisted

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: wiring the focus filter across all marketing impact dashboard tabs, which is the core objective of this PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description clearly maps to the changeset: it outlines type updates, classification parameter wiring across service/controller/SQL layers, template banner removals, and focus filter integration across dashboard tabs.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/LFXV2-1972-focus-filter-wiring

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

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 wires the Marketing Impact “Focus” filter end-to-end by mapping UI focus pills to Snowflake LF_SUB_DOMAIN_CLASSIFICATION, passing that classification through the Angular analytics service, BFF controller, and Snowflake queries, and ensuring key tabs re-fetch data when focus changes.

Changes:

  • Updated shared focus-program types/options and added FOCUS_TO_CLASSIFICATION + VALID_CLASSIFICATIONS to align with new Snowflake classification values.
  • Added optional classification query param support to multiple marketing-impact analytics endpoints (client → controller validation → Snowflake SQL filtering).
  • Updated Attribution and Performance Marketing tabs to re-fetch on focus changes and removed “not yet available at program level” banners.

Reviewed changes

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

Show a summary per file
File Description
packages/shared/src/interfaces/marketing-impact.interface.ts Updates MarketingImpactFocusProgram union to the new focus IDs used across the app.
packages/shared/src/constants/marketing-impact.constants.ts Updates focus pill options and maps focus IDs to Snowflake classification strings; adds VALID_CLASSIFICATIONS.
apps/lfx-one/src/server/services/project.service.ts Adds optional classification filtering to Snowflake queries for social reach, attribution, brand reach, and revenue impact (selectively where supported).
apps/lfx-one/src/server/controllers/analytics.controller.ts Accepts/validates classification query param and forwards it to ProjectService for the updated endpoints.
apps/lfx-one/src/app/shared/services/analytics.service.ts Adds optional classification query param plumbing to client analytics requests.
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/performance-marketing-tab/performance-marketing-tab.component.ts Re-fetches performance marketing data on focus changes and passes mapped classification.
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/performance-marketing-tab/performance-marketing-tab.component.html Removes focus-level “not yet available” info banner.
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/overview-tab/overview-tab.component.ts Passes mapped classification into Overview tab’s getRevenueImpact and getBrandReach.
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/attribution-section/attribution-section.component.ts Re-fetches attribution data on focus changes and passes mapped classification.
apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/attribution-section/attribution-section.component.html Removes focus-level “not yet available” info banner.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/lfx-one/src/server/controllers/analytics.controller.ts Outdated
Comment thread apps/lfx-one/src/app/shared/services/analytics.service.ts Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai 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

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/lfx-one/src/server/services/project.service.ts (1)

5062-5070: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Aggregate PAID_ADS_ATTRIBUTION on the single-foundation path.

Once LF_SUB_DOMAIN_CLASSIFICATION is part of this model, the non-umbrella query can return multiple rows for a foundation when classification is omitted. This method still consumes the first row only, so the “All programs” Revenue Impact view can underreport spend/revenue by dropping the other classifications.

Proposed fix
       : `
-        SELECT TOTAL_SPEND_YTD, TOTAL_IMPRESSIONS_YTD, TOTAL_CLICKS_YTD,
-               LINEAR_ROAS_YTD, AVG_CPC_YTD, CTR_YTD, CONVERSION_RATE_YTD,
-               FIRST_TOUCH_REVENUE_YTD, LAST_TOUCH_REVENUE_YTD,
-               LINEAR_REVENUE_YTD, TIME_DECAY_REVENUE_YTD,
-               SPEND_YOY_CHANGE_PCT, IMPRESSIONS_YOY_CHANGE_PCT
+        SELECT SUM(TOTAL_SPEND_YTD) AS TOTAL_SPEND_YTD,
+               SUM(TOTAL_IMPRESSIONS_YTD) AS TOTAL_IMPRESSIONS_YTD,
+               SUM(TOTAL_CLICKS_YTD) AS TOTAL_CLICKS_YTD,
+               CASE
+                 WHEN SUM(TOTAL_SPEND_YTD) > 0 THEN SUM(LINEAR_REVENUE_YTD) / SUM(TOTAL_SPEND_YTD)
+                 ELSE 0
+               END AS LINEAR_ROAS_YTD,
+               AVG(AVG_CPC_YTD) AS AVG_CPC_YTD,
+               AVG(CTR_YTD) AS CTR_YTD,
+               AVG(CONVERSION_RATE_YTD) AS CONVERSION_RATE_YTD,
+               SUM(FIRST_TOUCH_REVENUE_YTD) AS FIRST_TOUCH_REVENUE_YTD,
+               SUM(LAST_TOUCH_REVENUE_YTD) AS LAST_TOUCH_REVENUE_YTD,
+               SUM(LINEAR_REVENUE_YTD) AS LINEAR_REVENUE_YTD,
+               SUM(TIME_DECAY_REVENUE_YTD) AS TIME_DECAY_REVENUE_YTD,
+               AVG(SPEND_YOY_CHANGE_PCT) AS SPEND_YOY_CHANGE_PCT,
+               AVG(IMPRESSIONS_YOY_CHANGE_PCT) AS IMPRESSIONS_YOY_CHANGE_PCT
         FROM ANALYTICS.PLATINUM_LFX_ONE.PAID_ADS_ATTRIBUTION
         WHERE FOUNDATION_SLUG = ?
           ${classificationFilter}
       `;

Also applies to: 5217-5217

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/lfx-one/src/server/services/project.service.ts` around lines 5062 -
5070, The query against ANALYTICS.PLATINUM_LFX_ONE.PAID_ADS_ATTRIBUTION must
aggregate rows for a foundation when classification is omitted; change the
SELECT to use SUM(...) for raw totals (TOTAL_SPEND_YTD, TOTAL_IMPRESSIONS_YTD,
TOTAL_CLICKS_YTD, FIRST_TOUCH_REVENUE_YTD, LAST_TOUCH_REVENUE_YTD,
LINEAR_REVENUE_YTD, TIME_DECAY_REVENUE_YTD, SPEND_YOY_CHANGE_PCT,
IMPRESSIONS_YOY_CHANGE_PCT as appropriate) and compute derived rates from those
sums (e.g., CTR_YTD =
SUM(TOTAL_CLICKS_YTD)/NULLIF(SUM(TOTAL_IMPRESSIONS_YTD),0), AVG_CPC_YTD =
SUM(TOTAL_SPEND_YTD)/NULLIF(SUM(TOTAL_CLICKS_YTD),0), CONVERSION_RATE_YTD and
LINEAR_ROAS_YTD similarly) so the single-foundation path doesn’t drop other
classification rows; keep using the existing classificationFilter parameter but
ensure the SQL includes GROUP BY FOUNDATION_SLUG (or performs aggregation
unconditionally) and apply the same change at the other occurrence referenced
around line 5217.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@apps/lfx-one/src/server/services/project.service.ts`:
- Around line 5062-5070: The query against
ANALYTICS.PLATINUM_LFX_ONE.PAID_ADS_ATTRIBUTION must aggregate rows for a
foundation when classification is omitted; change the SELECT to use SUM(...) for
raw totals (TOTAL_SPEND_YTD, TOTAL_IMPRESSIONS_YTD, TOTAL_CLICKS_YTD,
FIRST_TOUCH_REVENUE_YTD, LAST_TOUCH_REVENUE_YTD, LINEAR_REVENUE_YTD,
TIME_DECAY_REVENUE_YTD, SPEND_YOY_CHANGE_PCT, IMPRESSIONS_YOY_CHANGE_PCT as
appropriate) and compute derived rates from those sums (e.g., CTR_YTD =
SUM(TOTAL_CLICKS_YTD)/NULLIF(SUM(TOTAL_IMPRESSIONS_YTD),0), AVG_CPC_YTD =
SUM(TOTAL_SPEND_YTD)/NULLIF(SUM(TOTAL_CLICKS_YTD),0), CONVERSION_RATE_YTD and
LINEAR_ROAS_YTD similarly) so the single-foundation path doesn’t drop other
classification rows; keep using the existing classificationFilter parameter but
ensure the SQL includes GROUP BY FOUNDATION_SLUG (or performs aggregation
unconditionally) and apply the same change at the other occurrence referenced
around line 5217.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 95ec9653-f952-4e95-95b4-946170961228

📥 Commits

Reviewing files that changed from the base of the PR and between 5f4c0ed and 6cda1e7.

📒 Files selected for processing (10)
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/attribution-section/attribution-section.component.html
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/attribution-section/attribution-section.component.ts
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/overview-tab/overview-tab.component.ts
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/performance-marketing-tab/performance-marketing-tab.component.html
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/performance-marketing-tab/performance-marketing-tab.component.ts
  • apps/lfx-one/src/app/shared/services/analytics.service.ts
  • apps/lfx-one/src/server/controllers/analytics.controller.ts
  • apps/lfx-one/src/server/services/project.service.ts
  • packages/shared/src/constants/marketing-impact.constants.ts
  • packages/shared/src/interfaces/marketing-impact.interface.ts
💤 Files with no reviewable changes (2)
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/attribution-section/attribution-section.component.html
  • apps/lfx-one/src/app/modules/dashboards/marketing-impact/components/performance-marketing-tab/performance-marketing-tab.component.html

mrautela365 added a commit that referenced this pull request May 27, 2026
- validation.helper.ts: extract getValidatedClassification() helper
  to deduplicate classification parsing across 6 controller actions
  (per copilot[bot])
- analytics.service.ts: extract buildFoundationParams() helper to
  deduplicate param construction across 6 methods (per copilot[bot])
- project.service.ts: aggregate PAID_ADS_ATTRIBUTION non-umbrella
  query with SUM/CASE for derived rates to prevent row-dropping when
  classification is omitted (per coderabbit[bot]); also fix umbrella
  query to compute ROAS/CTR/CPC from sums instead of naive AVG

Resolves 3 review threads.

Signed-off-by: Misha Rautela <mrautela@linuxfoundation.org>
Copilot AI review requested due to automatic review settings May 27, 2026 20:46
@mrautela365
Copy link
Copy Markdown
Contributor Author

Review Feedback Addressed

Commit: 58500c0

Changes Made

  • validation.helper.ts: Extracted getValidatedClassification() helper to deduplicate classification validation across 6 controller actions (per copilot[bot])
  • analytics.service.ts: Added private buildFoundationParams() helper to eliminate repeated param construction across 6 methods (per copilot[bot])
  • project.service.ts: Aggregated PAID_ADS_ATTRIBUTION non-umbrella query with SUM/CASE for derived rates (ROAS, CTR, CPC, conversion rate) to prevent row-dropping when classification is omitted; also fixed umbrella query to compute rates from sums instead of naive AVG (per coderabbit[bot])

Threads Resolved

2 of 2 inline threads addressed. CodeRabbit out-of-diff finding (PAID_ADS_ATTRIBUTION aggregation) also addressed in this commit.

Copy link
Copy Markdown
Contributor

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

Copilot reviewed 11 out of 11 changed files in this pull request and generated 5 comments.

Comment thread apps/lfx-one/src/server/services/project.service.ts
Comment thread apps/lfx-one/src/server/services/project.service.ts Outdated
Comment thread apps/lfx-one/src/app/shared/services/analytics.service.ts
Comment thread apps/lfx-one/src/app/shared/services/analytics.service.ts Outdated
Comment thread apps/lfx-one/src/server/services/project.service.ts
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
apps/lfx-one/src/server/helpers/validation.helper.ts (1)

148-156: ⚡ Quick win

Add a JSDoc block for the exported classification validator.

getValidatedClassification is exported and should include a short JSDoc for params/return/throw behavior.

As per coding guidelines "Add JSDoc comments for public functions and exported modules".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/lfx-one/src/server/helpers/validation.helper.ts` around lines 148 - 156,
Add a JSDoc comment block above the exported function getValidatedClassification
describing its purpose, parameters, return value, and throws behavior: document
that it accepts (req: Request) and (operation: string), returns a string |
undefined for a validated classification, and throws
ServiceValidationError.forField when the classification is present but not in
VALID_CLASSIFICATIONS; also mention it reads the query via getStringQueryParam
and list the allowed values (or reference VALID_CLASSIFICATIONS) in the
description.
apps/lfx-one/src/app/shared/services/analytics.service.ts (1)

901-902: ⚡ Quick win

Keep JSDoc aligned with the new classification parameter.

These public methods now accept classification, but their docs still only describe foundationSlug. Please add @param classification to each updated method docblock.

As per coding guidelines "Add JSDoc comments for public functions and exported modules".

Also applies to: 1208-1209, 1256-1257, 1281-1283

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/lfx-one/src/app/shared/services/analytics.service.ts` around lines 901 -
902, The JSDoc for the public analytics methods that now accept an optional
classification parameter (for example getSocialReach) is missing `@param` for
classification; update each affected method's docblock (including the docblocks
at the other changed locations) to add a line like "`@param` classification
Optional string to filter results by classification" (or similar wording
consistent with existing docs), ensuring the type and optionality are specified
and the description explains how the parameter is used; apply this to
getSocialReach and the other public methods that were changed in the same file.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@apps/lfx-one/src/app/shared/services/analytics.service.ts`:
- Around line 901-902: The JSDoc for the public analytics methods that now
accept an optional classification parameter (for example getSocialReach) is
missing `@param` for classification; update each affected method's docblock
(including the docblocks at the other changed locations) to add a line like
"`@param` classification Optional string to filter results by classification" (or
similar wording consistent with existing docs), ensuring the type and
optionality are specified and the description explains how the parameter is
used; apply this to getSocialReach and the other public methods that were
changed in the same file.

In `@apps/lfx-one/src/server/helpers/validation.helper.ts`:
- Around line 148-156: Add a JSDoc comment block above the exported function
getValidatedClassification describing its purpose, parameters, return value, and
throws behavior: document that it accepts (req: Request) and (operation:
string), returns a string | undefined for a validated classification, and throws
ServiceValidationError.forField when the classification is present but not in
VALID_CLASSIFICATIONS; also mention it reads the query via getStringQueryParam
and list the allowed values (or reference VALID_CLASSIFICATIONS) in the
description.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 850ae845-f611-4da6-be55-666dc5b15159

📥 Commits

Reviewing files that changed from the base of the PR and between e369fcc and 58500c0.

📒 Files selected for processing (4)
  • apps/lfx-one/src/app/shared/services/analytics.service.ts
  • apps/lfx-one/src/server/controllers/analytics.controller.ts
  • apps/lfx-one/src/server/helpers/validation.helper.ts
  • apps/lfx-one/src/server/services/project.service.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/lfx-one/src/server/services/project.service.ts

mrautela365 added a commit that referenced this pull request May 27, 2026
- project.service.ts: fix getSocialReach JSDoc to reference only
  PAID_SOCIAL_REACH_BY_PROJECT_CHANNEL_MONTH (per copilot[bot])
- analytics.service.ts: update classification param examples from
  'Events'/'Corporate' to 'LF Events'/'LF Corporate' (per copilot[bot])

Resolves 3 review threads. 2 threads about monthlyTrendQuery on
PAID_SOCIAL_REACH_BY_PROJECT_MONTH are false positives — that table
now has LF_SUB_DOMAIN_CLASSIFICATION per data team update.

Signed-off-by: Misha Rautela <mrautela@linuxfoundation.org>
@mrautela365
Copy link
Copy Markdown
Contributor Author

Review Feedback Addressed — Cycle 2

Commit: d792b7e

Changes Made

  • project.service.ts: Fixed getSocialReach JSDoc to reference only PAID_SOCIAL_REACH_BY_PROJECT_CHANNEL_MONTH (per copilot[bot])
  • analytics.service.ts: Updated classification param examples from 'Events'/'Corporate' to 'LF Events'/'LF Corporate' in getWebActivitiesSummary and getEmailCtr doc comments (per copilot[bot])

No Change Needed

  • project.service.ts lines 5110/5241: copilot[bot] flagged monthlyTrendQuery applying classification to PAID_SOCIAL_REACH_BY_PROJECT_MONTH, citing the PR description. This table now has LF_SUB_DOMAIN_CLASSIFICATION per a data team update after the PR was opened — the filter is intentional.

Threads Resolved

5 of 5 unresolved threads addressed (3 code fixes, 2 false positives).

mrautela365 added a commit that referenced this pull request May 27, 2026
Address coderabbitai[bot] nitpick comments:

- validation.helper.ts: add JSDoc to getValidatedClassification()
- analytics.service.ts: add @param classification to getSocialReach,
  getBrandReach, getRevenueImpact, getMarketingAttribution JSDocs

LFXV2-1972

Signed-off-by: Misha Rautela <mrautela@linuxfoundation.org>
Copilot AI review requested due to automatic review settings May 27, 2026 23:34
@mrautela365
Copy link
Copy Markdown
Contributor Author

Review Feedback Addressed

Commit: 72dbade

Changes Made

  • validation.helper.ts: Added JSDoc block to getValidatedClassification() documenting params, return value, and throws behavior (per coderabbitai[bot])
  • analytics.service.ts: Added @param classification to JSDoc for getSocialReach, getBrandReach, getRevenueImpact, getMarketingAttribution — aligning with existing docs on getWebActivitiesSummary and getEmailCtr (per coderabbitai[bot])

No Change Needed

  • project.service.ts:5062-5070: Aggregate PAID_ADS_ATTRIBUTION query — already uses SUM/CASE aggregation as of commit 58500c0. CodeRabbit's suggestion was based on an earlier commit (6cda1e7) (per coderabbitai[bot])

Threads Resolved

All 7 threads were already resolved in prior iterations. This commit addresses 2 nitpick items from the coderabbitai[bot] review body.

Copy link
Copy Markdown
Contributor

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

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.

Comment thread apps/lfx-one/src/server/services/project.service.ts
Update MarketingImpactFocusProgram type and FOCUS_TO_CLASSIFICATION
mapping to match new Snowflake LF_SUB_DOMAIN_CLASSIFICATION values
(LF Corporate, LF Events, LF Training, LFX Platform, Project
Websites). Add classification query param support to getSocialReach,
getBrandReach, getRevenueImpact, and getMarketingAttribution
endpoints. Wire Attribution and Performance Marketing tabs with
combineLatest pattern to re-fetch on focus change; pass
classification to getRevenueImpact and getBrandReach in Overview tab.
Remove "not yet available" info banners from Attribution and
Performance Marketing templates. Apply classification filter
selectively — only to Snowflake tables that have the column.

LFXV2-1972

Signed-off-by: Misha Rautela <mrautela@linuxfoundation.org>
PAID_SOCIAL_REACH_BY_PROJECT_MONTH now has LF_SUB_DOMAIN_CLASSIFICATION.
Add GROUP BY aggregation and classification WHERE clause to the
monthlyTrendQuery in getRevenueImpact so the paid media monthly trend
respects the focus filter.

LFXV2-1972

Signed-off-by: Misha Rautela <mrautela@linuxfoundation.org>
- validation.helper.ts: extract getValidatedClassification() helper
  to deduplicate classification parsing across 6 controller actions
  (per copilot[bot])
- analytics.service.ts: extract buildFoundationParams() helper to
  deduplicate param construction across 6 methods (per copilot[bot])
- project.service.ts: aggregate PAID_ADS_ATTRIBUTION non-umbrella
  query with SUM/CASE for derived rates to prevent row-dropping when
  classification is omitted (per coderabbit[bot]); also fix umbrella
  query to compute ROAS/CTR/CPC from sums instead of naive AVG

Resolves 3 review threads.

Signed-off-by: Misha Rautela <mrautela@linuxfoundation.org>
- project.service.ts: fix getSocialReach JSDoc to reference only
  PAID_SOCIAL_REACH_BY_PROJECT_CHANNEL_MONTH (per copilot[bot])
- analytics.service.ts: update classification param examples from
  'Events'/'Corporate' to 'LF Events'/'LF Corporate' (per copilot[bot])

Resolves 3 review threads. 2 threads about monthlyTrendQuery on
PAID_SOCIAL_REACH_BY_PROJECT_MONTH are false positives — that table
now has LF_SUB_DOMAIN_CLASSIFICATION per data team update.

Signed-off-by: Misha Rautela <mrautela@linuxfoundation.org>
Address coderabbitai[bot] nitpick comments:

- validation.helper.ts: add JSDoc to getValidatedClassification()
- analytics.service.ts: add @param classification to getSocialReach,
  getBrandReach, getRevenueImpact, getMarketingAttribution JSDocs

LFXV2-1972

Signed-off-by: Misha Rautela <mrautela@linuxfoundation.org>
Copilot AI review requested due to automatic review settings May 28, 2026 21:27
@mrautela365 mrautela365 force-pushed the feat/LFXV2-1972-focus-filter-wiring branch from 64168de to 5414922 Compare May 28, 2026 21:27
@mrautela365 mrautela365 merged commit 12b8834 into main May 28, 2026
9 of 10 checks passed
@mrautela365 mrautela365 deleted the feat/LFXV2-1972-focus-filter-wiring branch May 28, 2026 21:27
Copilot stopped reviewing on behalf of mrautela365 due to an error May 28, 2026 21:27
Copy link
Copy Markdown
Contributor

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

Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.

Comment on lines +155 to +163
export function getValidatedClassification(req: Request, operation: string): string | undefined {
const classification = getStringQueryParam(req, 'classification');
if (classification && !VALID_CLASSIFICATIONS.has(classification)) {
throw ServiceValidationError.forField('classification', `Invalid classification value. Allowed: ${[...VALID_CLASSIFICATIONS].join(', ')}`, {
operation,
});
}
return classification;
}
Comment on lines +158 to +160
throw ServiceValidationError.forField('classification', `Invalid classification value. Allowed: ${[...VALID_CLASSIFICATIONS].join(', ')}`, {
operation,
});
Comment on lines 5147 to 5153
FROM ANALYTICS.PLATINUM_LFX_ONE.PAID_SOCIAL_REACH_BY_PROJECT_MONTH
WHERE CAMPAIGN_MONTH >= DATE_TRUNC('month', DATEADD(month, -6, CURRENT_DATE()))
AND CAMPAIGN_MONTH < DATE_TRUNC('month', CURRENT_DATE())
${classificationFilter}
GROUP BY CAMPAIGN_MONTH
ORDER BY CAMPAIGN_MONTH DESC
LIMIT 6
import type { AttributionModelOption, MarketingImpactFocusProgram, MarketingImpactTabOption } from '../interfaces/marketing-impact.interface';

/** Focus program filter options for the Marketing Impact FOCUS bar. */
/** Focus program filter options for the Marketing Impact FOCUS bar. Labels match Snowflake LF_SUB_DOMAIN_CLASSIFICATION values. */
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.

3 participants