codeant-ai-for-open-source[bot] commented on code in PR #38403:
URL: https://github.com/apache/superset/pull/38403#discussion_r3012340417


##########
superset/mcp_service/chart/schemas.py:
##########
@@ -851,6 +852,111 @@ def validate_query_fields(self) -> 
"HandlebarsChartConfig":
         return self
 
 
+class BigNumberChartConfig(UnknownFieldCheckMixin):
+    model_config = ConfigDict(extra="ignore")
+
+    chart_type: Literal["big_number"] = Field(
+        ...,
+        description=(
+            "Chart type discriminator - MUST be 'big_number'. "
+            "Creates Big Number charts that display a single prominent "
+            "metric value. Set show_trendline=True with a temporal_column "
+            "for a number with trendline, or leave show_trendline=False "
+            "for a standalone number."
+        ),
+    )
+    metric: ColumnRef = Field(
+        ...,
+        description=(
+            "The metric to display as a big number. "
+            "Must include an aggregate function (e.g., SUM, COUNT)."
+        ),
+    )
+    temporal_column: str | None = Field(
+        None,
+        description=(
+            "Temporal column for the trendline x-axis. "
+            "Required when show_trendline is True."
+        ),
+        min_length=1,
+        max_length=255,
+        pattern=r"^[a-zA-Z0-9_][a-zA-Z0-9_\s\-\.]*$",
+    )
+    time_grain: TimeGrain | None = Field(
+        None,
+        description=(
+            "Time granularity for trendline data. "
+            "Common values: PT1H (hour), P1D (day), P1W (week), "
+            "P1M (month), P1Y (year)."
+        ),
+    )
+    show_trendline: bool = Field(
+        False,
+        description=(
+            "Show a trendline below the big number. "
+            "Requires 'temporal_column' to be set."
+        ),
+    )
+    subheader: str | None = Field(
+        None,
+        description="Subtitle text displayed below the big number",
+        max_length=500,
+    )
+    y_axis_format: str | None = Field(
+        None,
+        description=(
+            "Number format string for the metric value "
+            "(e.g., '$,.2f' for currency, ',.0f' for integers, "
+            "'.2%' for percentages)"
+        ),
+        max_length=50,
+    )
+    start_y_axis_at_zero: bool = Field(
+        True,
+        description="Anchor trendline y-axis at zero",
+    )
+    compare_lag: int | None = Field(
+        None,
+        description=(
+            "Number of time periods to compare against. "
+            "Displays a percentage change vs the prior period."
+        ),
+        ge=1,
+    )
+    filters: list[FilterConfig] | None = Field(
+        None,
+        description="Filters to apply",
+    )
+
+    @model_validator(mode="after")
+    def validate_trendline_fields(self) -> Self:
+        """Validate trendline requires temporal column."""
+        if self.show_trendline and not self.temporal_column:
+            raise ValueError(
+                "Big Number chart with show_trendline=True requires "
+                "'temporal_column'. Specify a date/time column for "
+                "the trendline x-axis."
+            )
+        if self.compare_lag and not self.show_trendline:
+            raise ValueError(
+                "compare_lag requires show_trendline=True. "
+                "Period comparison is only available for "
+                "trendline charts."
+            )
+        return self
+
+    @model_validator(mode="after")
+    def validate_metric_aggregate(self) -> Self:
+        """Ensure metric has an aggregate function."""
+        if not self.metric.aggregate:
+            raise ValueError(
+                "Big Number metric must have an aggregate function "
+                "(e.g., SUM, COUNT, AVG). Add 'aggregate' to the "
+                "metric specification."

Review Comment:
   **Suggestion:** The Big Number chart schema currently rejects metrics that 
reference saved dataset metrics (`saved_metric=True`) because the validator 
strictly checks for a non-null `aggregate`, even though `ColumnRef` and 
`map_big_number_config` fully support saved metrics; this causes valid 
configurations using saved metrics to fail validation instead of being accepted 
like other chart types. [logic error]
   
   <details>
   <summary><b>Severity Level:</b> Major ⚠️</summary>
   
   ```mdx
   - ❌ MCP big_number charts cannot use saved dataset metrics.
   - ⚠️ LLM clients must duplicate logic via ad-hoc aggregates.
   - ⚠️ Behavior inconsistent with pie and pivot chart metrics.
   - ⚠️ Advanced users hit confusing MISSING_BIG_NUMBER_AGGREGATE errors.
   ```
   </details>
   
   ```suggestion
           """Ensure metric is a valid metric reference (aggregate or saved 
metric)."""
           if not self.metric.is_metric:
               raise ValueError(
                   "Big Number metric must be either a saved dataset metric "
                   "or include an aggregate function (e.g., SUM, COUNT, AVG). "
                   "Set 'saved_metric': true to use a saved metric, or add "
                   "'aggregate' to the metric specification."
   ```
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. From an MCP client, call the `generate_chart` tool implemented in
   `superset/mcp_service/chart/tool/generate_chart.py` (see lines 200–279) with 
a request
   payload containing a Big Number chart config.
   
   2. Use a request of the form:
   
      `{"dataset_id": 1, "config": {"chart_type": "big_number", "metric": 
{"name":
      "my_saved_metric", "saved_metric": True}}}`.
   
      This follows the `ColumnRef` schema in 
`superset/mcp_service/chart/schemas.py:470-505`,
      where `saved_metric=True` means `name` refers to a saved dataset metric 
and aggregate
      is ignored.
   
   3. The MCP tool converts this to a dict via `request.model_dump()` and 
passes it into
   `ValidationPipeline.validate_request_with_warnings()` in
   `superset/mcp_service/chart/validation/pipeline.py:150-188`, which in turn 
calls
   `SchemaValidator.validate_request()` in
   `superset/mcp_service/chart/validation/schema_validator.py:40-60`.
   
   4. Inside `_pre_validate_big_number_config()` at 
`schema_validator.py:110-135`, the code
   inspects `config["metric"]` and fails because `metric.get("aggregate")` is 
falsy,
   returning `is_valid=False` with error_code `"MISSING_BIG_NUMBER_AGGREGATE"`, 
so the
   request is rejected before Pydantic BigNumberChartConfig is even 
constructed, preventing
   any Big Number chart that references a saved metric from being created via 
MCP.
   
   5. Independently, if another caller constructs `BigNumberChartConfig` 
directly in Python
   (as tests do for other cases in
   `tests/unit_tests/mcp_service/chart/test_big_number_chart.py:41-152`), using
   `BigNumberChartConfig(chart_type="big_number", 
metric=ColumnRef(name="my_saved_metric",
   saved_metric=True))`, the `ColumnRef` post-validator 
`clear_aggregate_for_saved_metric()`
   (`schemas.py:33-38`) clears `aggregate` to `None`, and
   `BigNumberChartConfig.validate_metric_aggregate()` (`schemas.py:94-103`) 
raises a
   `ValueError("Big Number metric must have an aggregate function ...")`, 
meaning the schema
   itself also rejects saved metrics even though `create_metric_object()`
   (`chart_utils.py:446-485`) and `map_big_number_config()` 
(`chart_utils.py:663-700`) fully
   support saved metrics.
   ```
   </details>
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** superset/mcp_service/chart/schemas.py
   **Line:** 950:955
   **Comment:**
        *Logic Error: The Big Number chart schema currently rejects metrics 
that reference saved dataset metrics (`saved_metric=True`) because the 
validator strictly checks for a non-null `aggregate`, even though `ColumnRef` 
and `map_big_number_config` fully support saved metrics; this causes valid 
configurations using saved metrics to fail validation instead of being accepted 
like other chart types.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F38403&comment_hash=baa9fa88ee79db099ffc48a55e377680db61a433f2426f60a4dd28f1850c6f57&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F38403&comment_hash=baa9fa88ee79db099ffc48a55e377680db61a433f2426f60a4dd28f1850c6f57&reaction=dislike'>👎</a>



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to