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

View File

@ -11,17 +11,19 @@ use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::io::Write;
use uuid::Uuid;
use crate::types::{DataMetadata, ColumnMetaData, SimpleType, ColumnType};
use serde_json::json;
#[derive(Debug, Serialize, Deserialize, Clone, FromSqlRow, AsExpression)]
#[diesel(sql_type = Jsonb)]
#[serde(rename_all = "camelCase")]
pub struct MetricYml {
pub name: String,
pub description: Option<String>,
#[serde(alias = "time_frame")]
pub time_frame: String,
pub sql: String,
#[serde(alias = "chart_config")]
pub chart_config: ChartConfig,
#[serde(alias = "dataset_ids")]
pub dataset_ids: Vec<Uuid>,
}
@ -457,16 +459,18 @@ impl ColumnLabelFormat {
pub fn new_boolean() -> Self {
Self::new_string() // Booleans use string formatting by default
}
/// 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();
for column in &metadata.column_metadata {
let format = Self::new_for_type(&column.simple_type);
formats.insert(column.name.clone(), format);
}
formats
}
}
@ -762,6 +766,10 @@ impl ToSql<Jsonb, Pg> for MetricYml {
#[cfg(test)]
mod tests {
use serde_json::json;
use crate::types::{ColumnMetaData, ColumnType, DataMetadata, SimpleType};
use super::*;
fn normalize_whitespace(s: &str) -> String {
@ -819,26 +827,26 @@ mod tests {
assert_eq!(number_format.number_separator_style, Some(",".to_string()));
assert_eq!(number_format.minimum_fraction_digits, Some(0));
assert_eq!(number_format.maximum_fraction_digits, Some(2));
// Test string format
let string_format = ColumnLabelFormat::new_string();
assert_eq!(string_format.column_type, "string");
assert_eq!(string_format.style, "string");
assert_eq!(string_format.number_separator_style, None);
// Test date format
let date_format = ColumnLabelFormat::new_date();
assert_eq!(date_format.column_type, "date");
assert_eq!(date_format.style, "date");
assert_eq!(date_format.date_format, Some("auto".to_string()));
assert_eq!(date_format.is_utc, Some(false));
// Test boolean format - should be same as string
let boolean_format = ColumnLabelFormat::new_boolean();
assert_eq!(boolean_format.column_type, "string");
assert_eq!(boolean_format.style, "string");
}
#[test]
fn test_generate_formats_from_metadata() {
// Create test metadata
@ -872,20 +880,20 @@ mod tests {
},
],
};
// Generate formats
let formats = ColumnLabelFormat::generate_formats_from_metadata(&metadata);
// Check we have formats for all columns
assert_eq!(formats.len(), 3);
// Check individual formats
let id_format = formats.get("id").unwrap();
assert_eq!(id_format.column_type, "number");
let name_format = formats.get("name").unwrap();
assert_eq!(name_format.column_type, "string");
let date_format = formats.get("created_at").unwrap();
assert_eq!(date_format.column_type, "date");
assert_eq!(date_format.style, "date");

View File

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