things are working good

This commit is contained in:
dal 2025-04-04 12:40:53 -06:00
parent 49ec28142f
commit 773dc9edee
No known key found for this signature in database
GPG Key ID: 16F4B0E1E9F61122
3 changed files with 107 additions and 99 deletions

View File

@ -109,8 +109,8 @@ pub const METRIC_YML_SCHEMA: &str = r##"
# #
# name: "Your Metric Title" # name: "Your Metric Title"
# description: "A detailed description of what this metric measures and how it should be interpreted" # Optional # description: "A detailed description of what this metric measures and how it should be interpreted" # Optional
# dataset_ids: ["123e4567-e89b-12d3-a456-426614174000"] # Dataset UUIDs (not names) # datasetIds: ["123e4567-e89b-12d3-a456-426614174000"] # Dataset UUIDs (not names)
# time_frame: "Last 30 days" # Human-readable time period covered by the query # timeFrame: "Last 30 days" # Human-readable time period covered by the query
# sql: | # sql: |
# SELECT # SELECT
# date, # date,
@ -118,26 +118,26 @@ pub const METRIC_YML_SCHEMA: &str = r##"
# FROM sales # FROM sales
# GROUP BY date # GROUP BY date
# #
# chart_config: # chartConfig:
# selected_chart_type: "bar" # One of: bar, line, scatter, pie, combo, metric, table # selectedChartType: "bar" # One of: bar, line, scatter, pie, combo, metric, table
# column_label_formats: { # REQUIRED - Must define formatting for all columns # columnLabelFormats: { # REQUIRED - Must define formatting for all columns
# "date": { # "date": {
# "column_type": "date", # "columnType": "date",
# "style": "date", # "style": "date",
# "date_format": "MMM DD, YYYY" # "dateFormat": "MMM DD, YYYY"
# }, # },
# "total": { # "total": {
# "column_type": "number", # "columnType": "number",
# "style": "currency", # "style": "currency",
# "currency": "USD", # "currency": "USD",
# "minimum_fraction_digits": 2 # "minimumFractionDigits": 2
# } # }
# } # }
# bar_and_line_axis: {...} # Required for bar and line charts OR # barAndLineAxis: {...} # Required for bar and line charts OR
# scatter_axis: {...} # Required for scatter charts OR # scatterAxis: {...} # Required for scatter charts OR
# pie_chart_axis: {...} # Required for pie charts OR # pieChartAxis: {...} # Required for pie charts OR
# combo_chart_axis: {...} # Required for combo charts OR # comboChartAxis: {...} # Required for combo charts OR
# metric_column_id: "column_id" # Required for metric charts # metricColumnId: "column_id" # Required for metric charts
# ------------------------------------- # -------------------------------------
type: object type: object
@ -156,7 +156,7 @@ properties:
description: "A detailed description of what this metric measures and how it should be interpreted" description: "A detailed description of what this metric measures and how it should be interpreted"
# DATASET IDS # DATASET IDS
dataset_ids: datasetIds:
type: array type: array
description: "UUIDs of datasets this metric belongs to" description: "UUIDs of datasets this metric belongs to"
items: items:
@ -165,7 +165,7 @@ properties:
description: "UUID string of the dataset (not the dataset name)" description: "UUID string of the dataset (not the dataset name)"
# TIME FRAME # TIME FRAME
time_frame: timeFrame:
type: string type: string
description: "Human-readable time period covered by the query (e.g., 'Last 30 days', 'All time', 'August 1, 2024 - January 1, 2025', 'Comparison: August 2025 to August 2024')" description: "Human-readable time period covered by the query (e.g., 'Last 30 days', 'All time', 'August 1, 2024 - January 1, 2025', 'Comparison: August 2025 to August 2024')"
@ -191,7 +191,7 @@ properties:
description: "SQL query using YAML pipe syntax (|)" description: "SQL query using YAML pipe syntax (|)"
# CHART CONFIGURATION # CHART CONFIGURATION
chart_config: chartConfig:
description: "Visualization settings (must match one chart type)" description: "Visualization settings (must match one chart type)"
oneOf: # REQUIRED oneOf: # REQUIRED
- $ref: "#/definitions/bar_line_chart_config" - $ref: "#/definitions/bar_line_chart_config"
@ -203,25 +203,25 @@ properties:
required: required:
- name - name
- dataset_ids - datasetIds
- time_frame - timeFrame
- sql - sql
- chart_config - chartConfig
definitions: definitions:
# BASE CHART CONFIG (common to all chart types) # BASE CHART CONFIG (common to all chart types)
base_chart_config: base_chart_config:
type: object type: object
properties: properties:
selected_chart_type: selectedChartType:
type: string type: string
description: "Chart type (bar, line, scatter, pie, combo, metric, table)" description: "Chart type (bar, line, scatter, pie, combo, metric, table)"
column_label_formats: columnLabelFormats:
type: object type: object
description: The formatting for each column. description: The formatting for each column.
additionalProperties: additionalProperties:
$ref: "#/definitions/column_label_format" $ref: "#/definitions/column_label_format"
column_settings: columnSettings:
type: object type: object
description: "Visual settings {columnId: settingsObject}" description: "Visual settings {columnId: settingsObject}"
additionalProperties: additionalProperties:
@ -230,11 +230,11 @@ definitions:
type: array type: array
items: items:
type: string type: string
show_legend: showLegend:
type: boolean type: boolean
grid_lines: gridLines:
type: boolean type: boolean
goal_lines: goalLines:
type: array type: array
items: items:
$ref: "#/definitions/goal_line" $ref: "#/definitions/goal_line"
@ -243,29 +243,29 @@ definitions:
items: items:
$ref: "#/definitions/trendline" $ref: "#/definitions/trendline"
required: required:
- selected_chart_type - selectedChartType
- column_label_formats - columnLabelFormats
# COLUMN FORMATTING # COLUMN FORMATTING
column_label_format: columnLabelFormat:
type: object type: object
properties: properties:
column_type: columnType:
type: string type: string
description: "number, string, date" description: "number, string, date"
style: style:
type: string type: string
enum: ["currency", "percent", "number", "date", "string"] enum: ["currency", "percent", "number", "date", "string"]
display_name: displayName:
type: string type: string
description: "Custom display name for the column" description: "Custom display name for the column"
number_separator_style: numberSeparatorStyle:
type: string type: string
description: "Style for number separators" description: "Style for number separators"
minimum_fraction_digits: minimumFractionDigits:
type: integer type: integer
description: "Minimum number of fraction digits to display" description: "Minimum number of fraction digits to display"
maximum_fraction_digits: maximumFractionDigits:
type: integer type: integer
description: "Maximum number of fraction digits to display" description: "Maximum number of fraction digits to display"
multiplier: multiplier:
@ -277,45 +277,45 @@ definitions:
suffix: suffix:
type: string type: string
description: "Text to display after the value" description: "Text to display after the value"
replace_missing_data_with: replaceMissingDataWith:
description: "Value to display when data is missing" description: "Value to display when data is missing"
compact_numbers: compactNumbers:
type: boolean type: boolean
description: "Whether to display numbers in compact form (e.g., 1K, 1M)" description: "Whether to display numbers in compact form (e.g., 1K, 1M)"
currency: currency:
type: string type: string
description: "Currency code for currency formatting (e.g., USD, EUR)" description: "Currency code for currency formatting (e.g., USD, EUR)"
date_format: dateFormat:
type: string type: string
description: "Format string for date display" description: "Format string for date display"
use_relative_time: useRelativeTime:
type: boolean type: boolean
description: "Whether to display dates as relative time (e.g., '2 days ago')" description: "Whether to display dates as relative time (e.g., '2 days ago')"
is_utc: isUtc:
type: boolean type: boolean
description: "Whether to interpret dates as UTC" description: "Whether to interpret dates as UTC"
convert_number_to: convertNumberTo:
type: string type: string
description: "Convert number to a different format" description: "Convert number to a different format"
required: required:
- column_type - columnType
- style - style
# COLUMN VISUAL SETTINGS # COLUMN VISUAL SETTINGS
column_settings: column_settings:
type: object type: object
properties: properties:
show_data_labels: showDataLabels:
type: boolean type: boolean
column_visualization: columnVisualization:
type: string type: string
enum: ["bar", "line", "dot"] enum: ["bar", "line", "dot"]
line_width: lineWidth:
type: number type: number
line_style: lineStyle:
type: string type: string
enum: ["area", "line"] enum: ["area", "line"]
line_type: lineType:
type: string type: string
enum: ["normal", "smooth", "step"] enum: ["normal", "smooth", "step"]
@ -325,9 +325,9 @@ definitions:
- $ref: "#/definitions/base_chart_config" - $ref: "#/definitions/base_chart_config"
- type: object - type: object
properties: properties:
selected_chart_type: selectedChartType:
enum: ["bar", "line"] enum: ["bar", "line"]
bar_and_line_axis: barAndLineAxis:
type: object type: object
properties: properties:
x: x:
@ -345,24 +345,24 @@ definitions:
required: required:
- x - x
- y - y
bar_layout: barLayout:
type: string type: string
enum: ["horizontal", "vertical"] enum: ["horizontal", "vertical"]
bar_group_type: barGroupType:
type: string type: string
enum: ["stack", "group", "percentage-stack"] enum: ["stack", "group", "percentage-stack"]
required: required:
- selected_chart_type - selectedChartType
- bar_and_line_axis - barAndLineAxis
scatter_chart_config: scatter_chart_config:
allOf: allOf:
- $ref: "#/definitions/base_chart_config" - $ref: "#/definitions/base_chart_config"
- type: object - type: object
properties: properties:
selected_chart_type: selectedChartType:
enum: ["scatter"] enum: ["scatter"]
scatter_axis: scatterAxis:
type: object type: object
properties: properties:
x: x:
@ -377,17 +377,17 @@ definitions:
- x - x
- y - y
required: required:
- selected_chart_type - selectedChartType
- scatter_axis - scatterAxis
pie_chart_config: pie_chart_config:
allOf: allOf:
- $ref: "#/definitions/base_chart_config" - $ref: "#/definitions/base_chart_config"
- type: object - type: object
properties: properties:
selected_chart_type: selectedChartType:
enum: ["pie"] enum: ["pie"]
pie_chart_axis: pieChartAxis:
type: object type: object
properties: properties:
x: x:
@ -402,17 +402,17 @@ definitions:
- x - x
- y - y
required: required:
- selected_chart_type - selectedChartType
- pie_chart_axis - pieChartAxis
combo_chart_config: combo_chart_config:
allOf: allOf:
- $ref: "#/definitions/base_chart_config" - $ref: "#/definitions/base_chart_config"
- type: object - type: object
properties: properties:
selected_chart_type: selectedChartType:
enum: ["combo"] enum: ["combo"]
combo_chart_axis: comboChartAxis:
type: object type: object
properties: properties:
x: x:
@ -427,39 +427,39 @@ definitions:
- x - x
- y - y
required: required:
- selected_chart_type - selectedChartType
- combo_chart_axis - comboChartAxis
metric_chart_config: metric_chart_config:
allOf: allOf:
- $ref: "#/definitions/base_chart_config" - $ref: "#/definitions/base_chart_config"
- type: object - type: object
properties: properties:
selected_chart_type: selectedChartType:
enum: ["metric"] enum: ["metric"]
metric_column_id: metricColumnId:
type: string type: string
metric_value_aggregate: metricValueAggregate:
type: string type: string
enum: ["sum", "average", "median", "max", "min", "count", "first"] enum: ["sum", "average", "median", "max", "min", "count", "first"]
description: "Optional - only used when the user specifically requests it, otherwise leave blank" description: "Optional - only used when the user specifically requests it, otherwise leave blank"
required: required:
- selected_chart_type - selectedChartType
- metric_column_id - metricColumnId
table_chart_config: table_chart_config:
allOf: allOf:
- $ref: "#/definitions/base_chart_config" - $ref: "#/definitions/base_chart_config"
- type: object - type: object
properties: properties:
selected_chart_type: selectedChartType:
enum: ["table"] enum: ["table"]
table_column_order: tableColumnOrder:
type: array type: array
items: items:
type: string type: string
required: required:
- selected_chart_type - selectedChartType
# No additional required fields for table chart # No additional required fields for table chart
# HELPER OBJECTS # HELPER OBJECTS
@ -470,7 +470,7 @@ definitions:
type: boolean type: boolean
value: value:
type: number type: number
goal_line_label: goalLineLabel:
type: string type: string
trendline: trendline:
@ -479,11 +479,11 @@ definitions:
type: type:
type: string type: string
enum: ["average", "linear_regression", "min", "max", "median"] enum: ["average", "linear_regression", "min", "max", "median"]
column_id: columnId:
type: string type: string
required: required:
- type - type
- column_id - columnId
"##; "##;
pub const DASHBOARD_YML_SCHEMA: &str = r##" pub const DASHBOARD_YML_SCHEMA: &str = r##"
@ -497,18 +497,18 @@ pub const DASHBOARD_YML_SCHEMA: &str = r##"
# - id: 1 # Required row ID (integer) # - id: 1 # Required row ID (integer)
# items: # items:
# - id: "metric-uuid-1" # UUIDv4 of an existing metric # - id: "metric-uuid-1" # UUIDv4 of an existing metric
# column_sizes: [12] # Required - must sum to exactly 12 # columnSizes: [12] # Required - must sum to exactly 12
# - id: 2 # REQUIRED # - id: 2 # REQUIRED
# items: # items:
# - id: "metric-uuid-2" # - id: "metric-uuid-2"
# - id: "metric-uuid-3" # - id: "metric-uuid-3"
# column_sizes: [6, 6] # Required - must sum to exactly 12 # columnSizes: [6, 6] # Required - must sum to exactly 12
# #
# Rules: # Rules:
# 1. Each row can have up to 4 items # 1. Each row can have up to 4 items
# 2. Each row must have a unique ID # 2. Each row must have a unique ID
# 3. column_sizes is required and must specify the width for each item # 3. columnSizes is required and must specify the width for each item
# 4. Sum of column_sizes in a row must be exactly 12 # 4. Sum of columnSizes in a row must be exactly 12
# 5. Each column size must be at least 3 # 5. Each column size must be at least 3
# ---------------------------------------- # ----------------------------------------
@ -534,7 +534,7 @@ properties:
items: items:
type: array type: array
description: "Array of metrics to display in this row (max 4 items)" description: "Array of metrics to display in this row (max 4 items)"
max_items: 4 maxItems: 4
items: items:
type: object type: object
properties: properties:
@ -543,7 +543,7 @@ properties:
description: "UUIDv4 identifier of an existing metric" description: "UUIDv4 identifier of an existing metric"
required: required:
- id - id
column_sizes: columnSizes:
type: array type: array
description: "Required array of column sizes (must sum to exactly 12)" description: "Required array of column sizes (must sum to exactly 12)"
items: items:
@ -553,7 +553,7 @@ properties:
required: required:
- id - id
- items - items
- column_sizes - columnSizes
required: required:
- name - name
- description - description
@ -705,7 +705,7 @@ pub async fn process_metric_file_modification(
// Validate SQL and get dataset_id from the first dataset // Validate SQL and get dataset_id from the first dataset
if new_yml.dataset_ids.is_empty() { if new_yml.dataset_ids.is_empty() {
let error = "Missing required field 'dataset_ids'".to_string(); let error = "Missing required field 'dataset_iids'".to_string();
results.push(ModificationResult { results.push(ModificationResult {
file_id: file.id, file_id: file.id,
file_name: modification.file_name.clone(), file_name: modification.file_name.clone(),

View File

@ -11,17 +11,19 @@ use serde::{Deserialize, Serialize};
use serde_json::Value; use serde_json::Value;
use std::io::Write; use std::io::Write;
use uuid::Uuid; use uuid::Uuid;
use crate::types::{DataMetadata, ColumnMetaData, SimpleType, ColumnType};
use serde_json::json;
#[derive(Debug, Serialize, Deserialize, Clone, FromSqlRow, AsExpression)] #[derive(Debug, Serialize, Deserialize, Clone, FromSqlRow, AsExpression)]
#[diesel(sql_type = Jsonb)] #[diesel(sql_type = Jsonb)]
#[serde(rename_all = "camelCase")]
pub struct MetricYml { pub struct MetricYml {
pub name: String, pub name: String,
pub description: Option<String>, pub description: Option<String>,
#[serde(alias = "time_frame")]
pub time_frame: String, pub time_frame: String,
pub sql: String, pub sql: String,
#[serde(alias = "chart_config")]
pub chart_config: ChartConfig, pub chart_config: ChartConfig,
#[serde(alias = "dataset_ids")]
pub dataset_ids: Vec<Uuid>, pub dataset_ids: Vec<Uuid>,
} }
@ -459,7 +461,9 @@ impl ColumnLabelFormat {
} }
/// Generate column formats from data metadata /// Generate column formats from data metadata
pub fn generate_formats_from_metadata(metadata: &crate::types::DataMetadata) -> indexmap::IndexMap<String, Self> { pub fn generate_formats_from_metadata(
metadata: &crate::types::DataMetadata,
) -> indexmap::IndexMap<String, Self> {
let mut formats = indexmap::IndexMap::new(); let mut formats = indexmap::IndexMap::new();
for column in &metadata.column_metadata { for column in &metadata.column_metadata {
@ -762,6 +766,10 @@ impl ToSql<Jsonb, Pg> for MetricYml {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use serde_json::json;
use crate::types::{ColumnMetaData, ColumnType, DataMetadata, SimpleType};
use super::*; use super::*;
fn normalize_whitespace(s: &str) -> String { fn normalize_whitespace(s: &str) -> String {

View File

@ -1408,7 +1408,7 @@ fn tool_modify_dashboards(id: String, content: String) -> Result<Vec<BusterReaso
id: file_id.clone(), id: file_id.clone(),
file_type: "dashboard".to_string(), file_type: "dashboard".to_string(),
file_name: file.name.clone(), file_name: file.name.clone(),
version_number: 1, version_number: file.version_number,
status: "completed".to_string(), status: "completed".to_string(),
file: BusterFileContent { file: BusterFileContent {
text: Some(file.yml_content), text: Some(file.yml_content),