Skip to content

[Refactor] ai report 데이터 추가 및 5각형 레이더 UI 추가#102

Merged
qwon999 merged 4 commits into
developfrom
refactor/ai-report
Feb 11, 2026
Merged

[Refactor] ai report 데이터 추가 및 5각형 레이더 UI 추가#102
qwon999 merged 4 commits into
developfrom
refactor/ai-report

Conversation

@jxhee99
Copy link
Copy Markdown
Collaborator

@jxhee99 jxhee99 commented Feb 11, 2026

🧾 ApiLog

✏️ Summary

ai 리포트 제공 데이터 추가 및 UI 개선했습니다.

📢 Motivation

리포트 품질 개선을 위해 진행했습니다.

📌 Type of Change

  • ✨ New Feature / 새로운 기능
  • 🐞 Bug Fix / 버그 수정
  • 💅 Style / UI Update / 스타일·UI 변경
  • 🧹 Refactor (non-breaking) / 리팩토링(비호환X)
  • 🧾 Docs / 문서
  • ✅ Test Added / Updated / 테스트 추가·수정
  • ⚙️ Build / CI / Config / 빌드·CI·설정
  • 🔥 Breaking Change / 호환성 깨짐
  • ♻️ Other / 기타 (설명)

🛠️ Implementation Details

[BE]

  • summary_sql 14일 범위 + CASE WHEN period 분리 (current/previous)
  • event_name GROUP BY 추가 + AVG(dwell_ms), COUNT(dwell_ms), AVG(scroll_pct), COUNT(scroll_pct) 컬럼 추가
  • 번들 빌드에서 delta_pct 계산 (device/browser/country/dwell/error/traffic)
  • Health Score 5축 계산: stability, engagement, content_consumption, retention, interactivity
  • Null 처리: 30건 미만 또는 전체의 10% 미만이면 해당 축 null

[FE]

  • 5각형 레이더 차트 구현

🧪 Testing

데이터 생성 실패 시 로그 데이터 부족인지 아니면 api key 미설정 때문인지 구분해서 테스트 진행했습니다.

🖼️ Screenshots / Demos

[데이터 생성 성공]
image

[데이터 생성 실패]
image

[데이터 부족시]
image

✅ Checklist

  • Tests pass locally / 로컬 테스트 통과
  • Lint & type checks pass / 린트·타입체크 통과
  • Docs updated if needed / 필요 시 문서 업데이트
  • Commit messages follow convention / 커밋 규칙 준수

@jxhee99 jxhee99 requested a review from qwon999 February 11, 2026 04:50
@jxhee99 jxhee99 self-assigned this Feb 11, 2026
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello @jxhee99, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 Pull Request는 AI 리포트의 품질과 사용자 경험을 향상시키기 위해 백엔드 데이터 처리 로직과 프론트엔드 UI를 개선합니다. 주간 변화율 계산을 위한 데이터 수집을 확장하고, 웹사이트의 전반적인 상태를 직관적으로 파악할 수 있는 Health Score를 도입하여 리포트의 깊이와 유용성을 높였습니다. 또한, 이 Health Score를 시각적으로 보여주는 레이더 차트를 추가하여 사용자가 데이터를 더 쉽게 이해하고 분석할 수 있도록 지원합니다.

Highlights

  • AI 리포트 데이터 수집 개선: AI 리포트 생성을 위한 데이터 수집 로직이 7일에서 14일로 확장되었으며, 현재 주와 이전 주 데이터를 분리하여 주간 변화율(delta_pct)을 계산할 수 있도록 업데이트되었습니다. summary_sql 쿼리에 event_name 그룹화 및 dwell_ms, scroll_pct 관련 통계가 추가되었습니다.
  • Health Score 도입: 안정성, 참여도, 콘텐츠 소비, 유지력, 상호작용의 5가지 축으로 구성된 새로운 Health Score 모델이 백엔드에 추가되었습니다. 이 점수는 데이터가 부족할 경우 null로 처리되는 로직을 포함합니다.
  • LLM 프롬프트 및 스키마 업데이트: LLM 프롬프트 버전이 v3에서 v4로 업데이트되었으며, LLM이 주간 변화율을 기반으로 진단 항목의 심각도를 판단하고 Health Score를 참조하도록 지침이 강화되었습니다. TrafficDiagnosis 스키마에 delta_pct 필드가 추가되었고, ReportResponsehealth_score가 포함되도록 변경되었습니다.
  • 5각형 레이더 차트 UI 구현: 프론트엔드에 Health Score를 시각적으로 표현하기 위한 5각형 레이더 차트 UI가 구현되었습니다. 또한, 진단 항목에 주간 변화율(delta_pct)을 표시하는 기능이 추가되었습니다.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • back/app/plugins/widgets/ai_report/schemas.py
    • TrafficDiagnosis 모델에 주간 변화율(delta_pct) 필드를 추가했습니다.
    • HealthScore 모델을 새로 정의하여 안정성, 참여도, 콘텐츠 소비, 유지력, 상호작용 지표를 포함했습니다.
    • ReportMeta의 prompt_version을 'v3'에서 'v4'로 업데이트했습니다.
    • ReportResponse 모델에 HealthScore를 포함하는 health_score 필드를 추가했습니다.
  • back/app/plugins/widgets/ai_report/service.py
    • _collect_report_bundle 함수를 수정하여 14일간의 데이터를 수집하고 현재 주와 이전 주로 분리했습니다.
    • summary_sql 쿼리에 event_name, period 컬럼 및 dwell_count, scroll_count, avg_scroll_pct 컬럼을 추가했습니다.
    • exit_sql 쿼리의 시간 범위 기준을 from_str에서 mid_str로 변경했습니다.
    • 데이터 집계 로직을 현재 및 이전 기간별로 분리하여 주간 변화율 계산을 위한 맵을 생성했습니다.
    • 안전하게 백분율 변화율을 계산하는 _pct_delta 헬퍼 함수를 추가했습니다.
    • device_share, browser_share, country_share, avg_dwell_by_device, error_analysis 항목에 주간 변화율(delta_pct 또는 delta_pp) 계산 로직을 추가했습니다.
    • Health Score의 5가지 축(안정성, 참여도, 콘텐츠 소비, 유지력, 상호작용)을 계산하고, 데이터 부족 시 null 처리 로직을 구현했습니다.
    • LLM 프롬프트 지침에 주간 변화율을 활용한 심각도 판단 규칙과 Health Score 참조 지침을 추가했습니다.
    • LLM 응답에 서버에서 계산된 health_score를 주입하도록 로직을 추가했습니다.
  • front/apps/dashboard/src/pages/ai-report.tsx
    • recharts 라이브러리에서 Radar, RadarChart 등 레이더 차트 관련 컴포넌트를 임포트했습니다.
    • TrafficDiagnosis 타입에 delta_pct 필드를 추가했습니다.
    • HealthScore 타입을 새로 정의하여 5가지 건강 지표를 포함했습니다.
    • Report 타입에 health_score 필드를 추가했습니다.
    • Health Score 관련 UI 텍스트(healthScoreTitle, healthInsufficient, hsStability 등)를 COPY 객체에 추가했습니다.
    • 진단 항목(diagnostics)에 delta_pct 값을 표시하는 UI를 추가했습니다.
    • HealthScoreCard 컴포넌트를 새로 구현하여 Health Score를 5각형 레이더 차트로 시각화했습니다.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request significantly enhances the AI report by introducing new data points and a 5-axis radar chart UI. The backend now collects 14 days of data to calculate week-over-week deltas for various metrics, which are then used to determine severity in diagnostics, and a new 'Health Score' model has been added, calculated server-side. The frontend has been updated to display these new delta percentages and visualize the health score, with LLM prompts updated to utilize these new data points effectively. However, critical security vulnerabilities were identified: a lack of site isolation in the data collection process could allow users to access aggregated analytics data from other sites, and the LLM prompt construction is vulnerable to injection via the user-provided analyst note. Additionally, the backend uses a broad Exception catch in _collect_report_bundle, which could mask specific issues, and some helper functions within _collect_report_bundle could be extracted for better modularity.

Comment on lines +184 to +185
device_type, browser_family, country_code, path, event_name,
CASE WHEN time >= TIMESTAMP '{mid_str}' THEN 'current' ELSE 'previous' END AS period,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

security-high high

Vulnerability: Broken Access Control (Missing Site Isolation)

The SQL query in _collect_report_bundle fetches analytics data without filtering by site_id. Since the application appears to be multi-tenant (as evidenced by the site_id parameter in the request and schema), this allows any user to generate a report that includes aggregated data from all sites in the database. This is a significant information exposure vulnerability.

Remediation

  1. Update _collect_report_bundle to accept a site_id parameter.
  2. Add a WHERE site_id = ... clause to all SQL queries in this function (e.g., WHERE site_id = '{site_id}' AND ...).
  3. Pass the site_id from generate_report to _collect_report_bundle.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

As I mentioned in the previous pr, it's not a multi-tenancy environment so it's not a problem

Comment on lines +528 to +529
"- `diagnostics`: 2~4 core issues by device/browser/country, citing actual numbers AND week-over-week delta_pct from the data. "
"Set severity based on the delta (High/Medium/Low per the rules). Include delta_pct as a number.\n"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

security-medium medium

Vulnerability: Prompt Injection

The LLM prompt construction incorporates the soft_prompt variable (derived from user input) without sanitization. This makes the feature vulnerable to prompt injection attacks, where a user can manipulate the analyst note to override system instructions and influence the generated report's content.

Remediation

Implement strict validation for the prompt input. Use clear delimiters to separate user-provided content from system instructions in the prompt, and explicitly instruct the LLM to treat the user input as a non-binding hint.

Comment on lines 239 to 240
except Exception as exc:
log.warning("InfluxDB query failed: %s", exc)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The _collect_report_bundle function uses a broad except Exception as exc: block. It's generally better to catch more specific exceptions to avoid masking unexpected errors and to handle different error types appropriately. For example, you might want to catch InfluxDBClient3Error or httpx.RequestError if those are the expected failure modes.


_collect_report_bundle 함수는 광범위한 except Exception as exc: 블록을 사용하고 있습니다. 예기치 않은 오류를 가리지 않고 다양한 오류 유형을 적절하게 처리하기 위해 더 구체적인 예외를 포착하는 것이 일반적으로 좋습니다. 예를 들어, 예상되는 실패 모드가 InfluxDBClient3Error 또는 httpx.RequestError인 경우 해당 예외를 포착할 수 있습니다.

@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
3.1% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@qwon999
Copy link
Copy Markdown
Collaborator

qwon999 commented Feb 11, 2026

LGTM :)
The pentagon has been upgraded!

@qwon999 qwon999 merged commit 242844d into develop Feb 11, 2026
1 of 4 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.

2 participants