diff --git a/Taskfile.yml b/Taskfile.yml index 41f179d3..4e74ae71 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -54,9 +54,9 @@ tasks: generate:schema: desc: Generate PowerSync and SQLite schema (uses local control plane) cmds: - - go generate ./internal/powersync - - go generate ./internal/sqlite - - sed '/^-- Auto-generated/d; /^-- Run .task generate/d' ../control-plane/internal/powersync/schema.sql > internal/chat/tools/query_schema.sql + - doppler run -- go generate ./internal/powersync + - doppler run -- go generate ./internal/sqlite + - sed '/^-- Auto-generated/d; /^-- Run .task generate/d' internal/sqlite/schema.sql > internal/app/chattools/query_schema.sql # =========================================================================== # Build diff --git a/internal/app/chattools/query_schema.sql b/internal/app/chattools/query_schema.sql index 65b13e4e..7f52c9b8 100644 --- a/internal/app/chattools/query_schema.sql +++ b/internal/app/chattools/query_schema.sql @@ -1,431 +1,308 @@ --- Tero Client Schema --- --- This describes the local SQLite database synced from the Tero control plane. --- All data is scoped to the authenticated user's account. --- --- Key concepts: --- services - Applications producing logs (e.g., 'checkout-service') --- log_events - Distinct event patterns within a service --- policies - AI-identified waste (health checks, duplicate fields, bloat) --- *_cache - Pre-computed status and metrics (query these for current state) --- --- All queries are READ-ONLY. This is a local sync of server data. +-- Code generated by go generate; DO NOT EDIT. +-- Source: PowerSync schema reflected from sqlite_master --- Live working set of entities (services, log events) referenced in a conversation CREATE TABLE conversation_contexts ( - id TEXT, -- Unique identifier - account_id TEXT, -- Denormalized for tenant isolation. Auto-set via trigger from conversation.account_id. - added_by TEXT, -- Who added this entity to context. user: added via @-reference, assistant: added by AI during chat. - conversation_id TEXT, -- Conversation this context belongs to - created_at TEXT, -- When the entity was added to context - entity_id TEXT, -- ID of the context entity - entity_type TEXT -- Type of the context entity. service: an application producing logs, log_event: a specific event pattern. + id TEXT, + account_id TEXT, + added_by TEXT, + conversation_id TEXT, + created_at TEXT, + entity_id TEXT, + entity_type TEXT ); --- Chat session between a user and the AI assistant within a workspace CREATE TABLE conversations ( - id TEXT, -- Unique identifier - account_id TEXT, -- Denormalized for tenant isolation. Auto-set via trigger from workspace.account_id. - created_at TEXT, -- When the conversation was created - title TEXT, -- AI-generated title, set after first exchange - user_id TEXT, -- WorkOS user ID who owns this conversation - view_id TEXT, -- If set, this conversation is for iterating on a specific view - workspace_id TEXT -- Workspace this conversation belongs to + id TEXT, + account_id TEXT, + created_at TEXT, + title TEXT, + user_id TEXT, + view_id TEXT, + workspace_id TEXT ); --- Cache table for datadog_account_statuses view. Refreshed by cron service. CREATE TABLE datadog_account_statuses_cache ( id TEXT, - account_id TEXT, -- Account ID (denormalized from Datadog account) - datadog_account_id TEXT, -- The Datadog account this status belongs to - disabled_services INTEGER, -- Services with DISABLED health - estimated_bytes_reduction_per_hour REAL, -- Account-wide estimated bytes reduction - estimated_cost_reduction_per_hour_bytes_usd REAL, -- Account-wide estimated bytes-based USD/hour savings - estimated_cost_reduction_per_hour_usd REAL, -- Account-wide estimated total USD/hour savings - estimated_cost_reduction_per_hour_volume_usd REAL, -- Account-wide estimated volume-based USD/hour savings - estimated_volume_reduction_per_hour REAL, -- Account-wide estimated volume reduction - health TEXT, -- Overall health of the Datadog account. DISABLED (integration turned off), INACTIVE (no data received), OK (healthy). - inactive_services INTEGER, -- Services with INACTIVE health - log_active_services INTEGER, -- Services not DISABLED or INACTIVE - log_event_analyzed_count INTEGER, -- Number of log events that have been analyzed - log_event_bytes_per_hour REAL, -- Discovered log event throughput in bytes/hour across all services - log_event_cost_per_hour_bytes_usd REAL, -- Discovered log event ingestion cost in USD/hour across all services - log_event_cost_per_hour_usd REAL, -- Discovered log event total cost in USD/hour across all services - log_event_cost_per_hour_volume_usd REAL, -- Discovered log event indexing cost in USD/hour across all services - log_event_count INTEGER, -- Total log events across all services - log_event_volume_per_hour REAL, -- Discovered log event throughput in events/hour across all services - log_service_count INTEGER, -- Total number of services - observed_bytes_per_hour_after REAL, -- Account-wide observed current bytes - observed_bytes_per_hour_before REAL, -- Account-wide observed pre-approval bytes - observed_cost_per_hour_after_bytes_usd REAL, -- Account-wide measured bytes-based USD/hour cost after approval - observed_cost_per_hour_after_usd REAL, -- Account-wide measured total USD/hour cost after approval - observed_cost_per_hour_after_volume_usd REAL, -- Account-wide measured volume-based USD/hour cost after approval - observed_cost_per_hour_before_bytes_usd REAL, -- Account-wide measured bytes-based USD/hour cost before approval - observed_cost_per_hour_before_usd REAL, -- Account-wide measured total USD/hour cost before approval - observed_cost_per_hour_before_volume_usd REAL, -- Account-wide measured volume-based USD/hour cost before approval - observed_volume_per_hour_after REAL, -- Account-wide observed current volume - observed_volume_per_hour_before REAL, -- Account-wide observed pre-approval volume - ok_services INTEGER, -- Services with OK health - policy_approved_count INTEGER, -- Policies approved by user - policy_dismissed_count INTEGER, -- Policies dismissed by user - policy_pending_count INTEGER, -- Policies awaiting user action - policy_pending_critical_count INTEGER, -- Pending policies with critical compliance severity - policy_pending_high_count INTEGER, -- Pending policies with high compliance severity - policy_pending_low_count INTEGER, -- Pending policies with low compliance severity - policy_pending_medium_count INTEGER, -- Pending policies with medium compliance severity - ready_for_use INTEGER, -- True when at least 1 log event has been analyzed - service_cost_per_hour_volume_usd REAL, -- Service-level indexing cost in USD/hour across all services - service_volume_per_hour REAL -- Ground-truth throughput in events/hour from service_log_volumes across all services + account_id TEXT, + approved_recommendation_count INTEGER, + current_bytes_per_hour REAL, + current_bytes_usd_per_hour REAL, + current_events_per_hour REAL, + current_service_events_per_hour REAL, + current_service_volume_usd_per_hour REAL, + current_total_usd_per_hour REAL, + current_volume_usd_per_hour REAL, + datadog_account_id TEXT, + disabled_services INTEGER, + dismissed_recommendation_count INTEGER, + estimated_bytes_per_hour REAL, + estimated_bytes_usd_per_hour REAL, + estimated_events_per_hour REAL, + estimated_total_usd_per_hour REAL, + estimated_volume_usd_per_hour REAL, + health TEXT, + impact_bytes_per_hour REAL, + impact_bytes_usd_per_hour REAL, + impact_events_per_hour REAL, + impact_total_usd_per_hour REAL, + impact_volume_usd_per_hour REAL, + inactive_services INTEGER, + log_active_services INTEGER, + log_event_analyzed_count INTEGER, + log_event_count INTEGER, + log_service_count INTEGER, + ok_services INTEGER, + pending_recommendation_count INTEGER, + policy_pending_critical_count INTEGER, + policy_pending_high_count INTEGER, + policy_pending_low_count INTEGER, + policy_pending_medium_count INTEGER, + ready_for_use INTEGER, + recommendation_count INTEGER ); --- Datadog integration configuration for an account, one per account CREATE TABLE datadog_accounts ( - id TEXT, -- Unique identifier of the Datadog configuration - account_id TEXT, -- Parent account this configuration belongs to - cost_per_gb_ingested REAL, -- Cost per GB of log data ingested (USD). NULL = using Datadog's published rate ($0.10/GB). Set to override with actual contract rate. - created_at TEXT, -- When the Datadog account was created - name TEXT, -- Display name for this Datadog account - site TEXT -- Datadog regional site. US1: datadoghq.com, US3: us3.datadoghq.com, US5: us5.datadoghq.com, EU1: datadoghq.eu, US1_FED: ddog-gov.com, AP1: ap1.datadoghq.com, AP2: ap2.datadoghq.com. + id TEXT, + account_id TEXT, + cost_per_gb_ingested REAL, + created_at TEXT, + name TEXT, + site TEXT ); --- Discovered Datadog log index where logs are stored (e.g., main, security, compliance) CREATE TABLE datadog_log_indexes ( - id TEXT, -- Unique identifier for this index record - account_id TEXT, -- Denormalized for tenant isolation. Auto-set via trigger from datadog_account.account_id. - cost_per_million_events_indexed REAL, -- Cost per million events indexed in this index (USD). NULL = using Datadog's published rate ($1.70/M). SIEM indexes cost more — set accordingly. - created_at TEXT, -- When this index was first discovered - datadog_account_id TEXT, -- The Datadog account this index belongs to - name TEXT -- Index name from Datadog (e.g., 'main', 'security', 'compliance') - this is the stable identifier -); - --- Ground truth record for a field in a log event. Accumulates metadata as more production data is observed. -CREATE TABLE log_event_fields ( - id TEXT, -- Unique identifier - account_id TEXT, -- Denormalized for tenant isolation. Auto-set via trigger from log_event.account_id. - baseline_avg_bytes REAL, -- Current trailing 7-day volume-weighted average bytes for this attribute. Refreshed on volume ingestion. - created_at TEXT, -- When this field was first discovered - field_path TEXT, -- Unambiguous path segments, e.g. {attributes, http, status} - log_event_id TEXT, -- The log event this field belongs to - -- Top-N observed values with proportions. Populated on-demand for fields that need faceting (e.g., user agents for bot detection). - -- Opaque JSON data. Query using SQLite json_extract() or json_each(). - value_distribution TEXT -); - --- AI-generated recommendation for a specific quality category on a log event, scoped to a workspace for approval -CREATE TABLE log_event_policies ( - id TEXT, -- Unique identifier - account_id TEXT, -- Denormalized for tenant isolation. Auto-set via trigger from workspace.account_id. - action TEXT, -- What this policy does when enforced: 'drop' (remove all events), 'sample' (keep at reduced rate), 'filter' (drop subset by field value), 'trim' (remove/truncate fields), 'none' (informational only). Auto-set via trigger. - -- Category-specific analysis from AI. JSON object with one field populated matching the category, containing the analysis and recommended actions. - -- JSON object. Fields: - -- $.pii_leakage - PII leakage analysis (optional) - -- $.pii_leakage.fields[] - List of fields that may contain PII - -- $.pii_leakage.fields[].path[] string[] - Path to field as array of segments - -- $.pii_leakage.fields[].types[] string[] - List of sensitive data types this field may contain - -- $.pii_leakage.fields[].observed boolean - Whether actual sensitive data was seen in examples - -- $.secrets_leakage - Secrets leakage analysis (optional) - -- $.secrets_leakage.fields[] - List of fields that may contain secrets - -- $.phi_leakage - PHI leakage analysis (optional) - -- $.phi_leakage.fields[] - List of fields that may contain PHI - -- $.payment_data_leakage - Payment data leakage analysis (optional) - -- $.payment_data_leakage.fields[] - List of fields that may contain payment data - -- $.health_checks - Health checks analysis (optional) - -- $.bot_traffic - Bot traffic analysis (optional) - -- $.bot_traffic.user_agent_field[] string[] - Path to user-agent field as array of segments - -- $.bot_traffic.bot_proportion number - Fraction of traffic identified as bot/crawler (optional) - -- $.debug_artifacts - Debug artifacts analysis (optional) - -- $.malformed - Malformed data analysis (optional) - -- $.broken_records - Broken records analysis (optional) - -- $.broken_records.min_interval_seconds number - Suggested minimum interval between kept events in seconds - -- $.commodity_traffic - Commodity traffic analysis (optional) - -- $.commodity_traffic.min_interval_seconds number - Suggested minimum interval between kept events in seconds - -- $.redundant_events - Redundant events analysis (optional) - -- $.dead_weight - Dead weight analysis (optional) - -- $.duplicate_fields - Duplicate fields analysis (optional) - -- $.duplicate_fields.pairs[] - List of duplicate field pairs - -- $.duplicate_fields.pairs[].remove[] string[][] - List of duplicate field paths to remove - -- $.duplicate_fields.pairs[].keep[] string[] - Canonical field path to keep - -- $.instrumentation_bloat - Instrumentation bloat analysis (optional) - -- $.instrumentation_bloat.fields[] string[][] - List of field paths that are instrumentation bloat - -- $.oversized_fields - Oversized fields analysis (optional) - -- $.oversized_fields.fields[] string[][] - List of field paths that are oversized - -- $.wrong_level - Wrong level analysis (optional) - -- $.wrong_level.current_level string - Current normalized severity level - -- $.wrong_level.suggested_level string - Suggested normalized severity level - -- - -- Example: json_extract(analysis, '$.field_name') - analysis TEXT, - approved_at TEXT, -- When this policy was approved by a user - approved_baseline_avg_bytes REAL, -- Baseline avg bytes frozen at approval time. Snapshot of log_event.baseline_avg_bytes. - approved_baseline_volume_per_hour REAL, -- Baseline volume/hour frozen at approval time. Snapshot of log_event.baseline_volume_per_hour. - approved_by TEXT, -- User ID who approved this policy - category TEXT, -- Quality issue category this policy addresses. Compliance: pii_leakage, secrets_leakage, phi_leakage, payment_data_leakage. Waste: health_checks, bot_traffic, debug_artifacts, malformed, broken_records, commodity_traffic, redundant_events, dead_weight. Quality: duplicate_fields, instrumentation_bloat, oversized_fields, wrong_level. - category_type TEXT, -- Type of problem: compliance (legal/security risk), waste (event-level cuts), or quality (field-level improvements). Auto-set via trigger from CategoryMeta. - created_at TEXT, -- When this policy was created - dismissed_at TEXT, -- When this policy was dismissed by a user - dismissed_by TEXT, -- User ID who dismissed this policy - log_event_id TEXT, -- The log event this policy applies to - severity TEXT, -- Max compliance severity across sensitivity types. NULL for non-compliance categories. Auto-set via trigger. Values: low, medium, high, critical. - subjective INTEGER, -- Whether this category requires AI judgment (true) vs mechanically verifiable (false). Auto-set via trigger from CategoryMeta. - workspace_id TEXT -- The workspace that owns this policy -); - --- Cache table for per-category policy aggregations. Refreshed by cron service. -CREATE TABLE log_event_policy_category_statuses_cache ( id TEXT, - account_id TEXT, -- Account ID for tenant isolation - action TEXT, -- What the policy does: drop (remove events), sample (reduce rate), filter (drop subset), trim (modify fields), none (informational) - approved_count INTEGER, -- Policies approved by user in this category - boundary TEXT, -- Where this category stops applying — what NOT to flag - category TEXT, -- Quality issue category (e.g., pii_leakage, noise, health_checks) - category_type TEXT, -- Type of problem: compliance (legal/security risk), waste (event-level cuts), quality (field-level improvements). - dismissed_count INTEGER, -- Policies dismissed by user in this category - display_name TEXT, -- Human-readable category name (e.g., 'PII Leakage') - estimated_bytes_reduction_per_hour REAL, -- Bytes/hour saved by all pending policies in this category combined - estimated_cost_reduction_per_hour_bytes_usd REAL, -- Estimated ingestion savings in USD/hour from pending policies in this category - estimated_cost_reduction_per_hour_usd REAL, -- Estimated total savings in USD/hour from pending policies in this category - estimated_cost_reduction_per_hour_volume_usd REAL, -- Estimated indexing savings in USD/hour from pending policies in this category - estimated_volume_reduction_per_hour REAL, -- Events/hour saved by all pending policies in this category combined - events_with_volumes INTEGER, -- Log events in this category that have volume data (subset of total_event_count) - pending_count INTEGER, -- Policies awaiting user review in this category - policy_pending_critical_count INTEGER, -- Pending policies with critical compliance severity - policy_pending_high_count INTEGER, -- Pending policies with high compliance severity - policy_pending_low_count INTEGER, -- Pending policies with low compliance severity - policy_pending_medium_count INTEGER, -- Pending policies with medium compliance severity - principle TEXT, -- What this category detects — the fundamental test for membership - subjective INTEGER, -- Whether this category requires AI judgment (true) vs mechanically verifiable (false) - total_event_count INTEGER -- Total log events that have a policy in this category + account_id TEXT, + cost_per_million_events_indexed REAL, + created_at TEXT, + datadog_account_id TEXT, + name TEXT ); --- Cache table for log_event_policy_statuses view. Refreshed by cron service. -CREATE TABLE log_event_policy_statuses_cache ( +CREATE TABLE log_event_recommendations ( id TEXT, - account_id TEXT, -- Account ID for tenant isolation - action TEXT, -- What the policy does: drop (remove events), sample (reduce rate), filter (drop subset), trim (modify fields), none (informational) - approved_at TEXT, -- When this policy was approved by a user - bytes_per_hour REAL, -- Current throughput of the targeted log event in bytes/hour - category TEXT, -- Quality issue category this policy addresses (e.g., pii_leakage, noise, health_checks) - category_type TEXT, -- Type of problem: compliance (legal/security risk), waste (event-level cuts), quality (field-level improvements). - created_at TEXT, -- When this policy was created - dismissed_at TEXT, -- When this policy was dismissed by a user - estimated_bytes_reduction_per_hour REAL, -- Bytes/hour saved if this policy applied alone. NULL if not estimable. - estimated_cost_reduction_per_hour_bytes_usd REAL, -- Estimated ingestion savings in USD/hour from bytes reduction - estimated_cost_reduction_per_hour_usd REAL, -- Estimated total savings in USD/hour (bytes + volume) - estimated_cost_reduction_per_hour_volume_usd REAL, -- Estimated indexing savings in USD/hour from volume reduction - estimated_volume_reduction_per_hour REAL, -- Events/hour saved if this policy applied alone. NULL if not estimable. - log_event_id TEXT, -- The log event this policy targets - log_event_name TEXT, -- Name of the targeted log event (denormalized for display) - policy_id TEXT, -- The policy this status row represents - service_id TEXT, -- Service that produces the targeted log event (denormalized) - service_name TEXT, -- Name of the service (denormalized for display) - severity TEXT, -- Max compliance severity across sensitivity types. NULL for non-compliance categories. Values: low, medium, high, critical. - status TEXT, -- User decision on this policy. PENDING (awaiting review), APPROVED (accepted for enforcement), DISMISSED (rejected by user). - subjective INTEGER, -- Whether this category requires AI judgment (true) vs mechanically verifiable (false) - survival_rate REAL, -- Fraction of events that survive this policy (0.0 = all dropped, 1.0 = all kept). NULL if not estimable. - volume_per_hour REAL, -- Current throughput of the targeted log event in events/hour - workspace_id TEXT -- The workspace that owns this policy + account_id TEXT, + action TEXT, + analysis TEXT, + approved_at TEXT, + approved_baseline_avg_bytes REAL, + approved_baseline_volume_per_hour REAL, + approved_by TEXT, + category TEXT, + category_type TEXT, + created_at TEXT, + dismissed_at TEXT, + dismissed_by TEXT, + log_event_id TEXT, + severity TEXT, + subjective INTEGER, + workspace_id TEXT ); --- Cache table for log_event_statuses view. Refreshed by cron service. CREATE TABLE log_event_statuses_cache ( id TEXT, - account_id TEXT, -- Account ID for tenant isolation - approved_policy_count INTEGER, -- Policies approved by user - bytes_per_hour REAL, -- Current throughput in bytes/hour (rolling 7-day) - cost_per_hour_bytes_usd REAL, -- Current ingestion cost in USD/hour - cost_per_hour_usd REAL, -- Current total cost in USD/hour (bytes + volume) - cost_per_hour_volume_usd REAL, -- Current indexing cost in USD/hour - dismissed_policy_count INTEGER, -- Policies dismissed by user - estimated_bytes_reduction_per_hour REAL, -- Bytes/hour saved by all policies combined - estimated_cost_reduction_per_hour_bytes_usd REAL, -- Estimated ingestion savings in USD/hour - estimated_cost_reduction_per_hour_usd REAL, -- Estimated total savings in USD/hour (bytes + volume) - estimated_cost_reduction_per_hour_volume_usd REAL, -- Estimated indexing savings in USD/hour - estimated_volume_reduction_per_hour REAL, -- Events/hour saved by all policies combined - has_been_analyzed INTEGER, -- Whether AI has analyzed this log event - has_volumes INTEGER, -- Whether volume data exists for this log event - log_event_id TEXT, -- The log event this status belongs to - observed_bytes_per_hour_after REAL, -- Measured bytes/hour after policy approval (current) - observed_bytes_per_hour_before REAL, -- Measured bytes/hour before first policy approval - observed_cost_per_hour_after_bytes_usd REAL, -- Measured ingestion cost after approval (current) - observed_cost_per_hour_after_usd REAL, -- Measured total cost after approval (current) - observed_cost_per_hour_after_volume_usd REAL, -- Measured indexing cost after approval (current) - observed_cost_per_hour_before_bytes_usd REAL, -- Measured ingestion cost before approval - observed_cost_per_hour_before_usd REAL, -- Measured total cost before approval - observed_cost_per_hour_before_volume_usd REAL, -- Measured indexing cost before approval - observed_volume_per_hour_after REAL, -- Measured events/hour after policy approval (current) - observed_volume_per_hour_before REAL, -- Measured events/hour before first policy approval - pending_policy_count INTEGER, -- Policies awaiting user action - policy_count INTEGER, -- Total non-dismissed policies - policy_pending_critical_count INTEGER, -- Pending policies with critical compliance severity - policy_pending_high_count INTEGER, -- Pending policies with high compliance severity - policy_pending_low_count INTEGER, -- Pending policies with low compliance severity - policy_pending_medium_count INTEGER, -- Pending policies with medium compliance severity - service_id TEXT, -- Service ID (denormalized from log_event) - volume_per_hour REAL -- Current throughput in events/hour (rolling 7-day) + account_id TEXT, + approved_recommendation_count INTEGER, + current_bytes_per_hour REAL, + current_bytes_usd_per_hour REAL, + current_events_per_hour REAL, + current_total_usd_per_hour REAL, + current_volume_usd_per_hour REAL, + dismissed_recommendation_count INTEGER, + effective_policy_enabled INTEGER, + estimated_bytes_per_hour REAL, + estimated_bytes_usd_per_hour REAL, + estimated_events_per_hour REAL, + estimated_total_usd_per_hour REAL, + estimated_volume_usd_per_hour REAL, + has_been_analyzed INTEGER, + has_volumes INTEGER, + impact_bytes_per_hour REAL, + impact_bytes_usd_per_hour REAL, + impact_events_per_hour REAL, + impact_total_usd_per_hour REAL, + impact_volume_usd_per_hour REAL, + log_event_id TEXT, + pending_recommendation_count INTEGER, + policy_pending_critical_count INTEGER, + policy_pending_high_count INTEGER, + policy_pending_low_count INTEGER, + policy_pending_medium_count INTEGER, + recommendation_count INTEGER, + service_id TEXT ); --- Distinct log message pattern discovered within a service. Defines how to parse and match logs using codecs and matchers. CREATE TABLE log_events ( - id TEXT, -- Unique identifier of the log event - account_id TEXT, -- Denormalized for tenant isolation. Auto-set via trigger from service.account_id. - baseline_avg_bytes REAL, -- Current trailing 7-day volume-weighted average bytes/event. Refreshed on volume ingestion. - baseline_volume_per_hour REAL, -- Current trailing 7-day average events/hour. Refreshed on volume ingestion. - created_at TEXT, -- When the log event was created - description TEXT, -- What the event is and what data instances carry. Helps engineers decide whether to look here. - event_nature TEXT, -- What this event records: system (internal mechanics), traffic (request flow), activity (actor+action+resource), control (access/permission decisions). - -- Sample log records captured during discovery, used for AI analysis and pattern validation - -- JSON array of objects. Each element: - -- $[0].timestamp - When the log event occurred (RFC3339) - -- $[0].body string - Log message content - -- $[0].severity_text string - Severity level as text (e.g., INFO, ERROR) - -- $[0].severity_number number - OTel severity level number (1-24) - -- $[0].trace_id string - Distributed trace ID (optional) - -- $[0].span_id string - Span ID within trace (optional) - -- $[0].attributes object - Log-level attributes (http.status, error.message, etc.) - -- $[0].resource_attributes object - Resource attributes (service.name, deployment.environment, etc.) - -- $[0].scope_attributes object - Instrumentation scope attributes (optional) - -- - -- Example: json_extract(examples, '$[0].field_name') + id TEXT, + account_id TEXT, + baseline_avg_bytes REAL, + baseline_volume_per_hour REAL, + created_at TEXT, + description TEXT, + event_nature TEXT, examples TEXT, - -- JSON rules that match incoming logs to this event. Each matcher specifies a field path, operator, and value. - -- JSON array of objects. Each element: - -- $[0].field_path[] string[] - Path to field as array of segments - -- $[0].match_type string - Match operator: exact, contains, starts_with, ends_with, regex, exists, missing - -- $[0].match_value string - Value to match against - -- $[0].case_insensitive boolean - Whether matching is case-insensitive (optional) - -- $[0].negate boolean - Whether to invert match result (optional) - -- - -- Example: json_extract(matchers, '$[0].field_name') matchers TEXT, - name TEXT, -- Snake_case identifier unique per service, e.g. nginx_access_log - service_id TEXT, -- Service that produces this event - severity TEXT, -- Predominant log severity level, derived from example records. Nullable when examples have no severity info. Values: debug, info, warn, error, other. - signal_purpose TEXT -- What role this event serves: diagnostic (investigate incidents), operational (system behavior), lifecycle (state transitions), ephemeral (transient state). + name TEXT, + service_id TEXT, + severity TEXT, + signal_purpose TEXT ); --- Single message in a chat conversation. Append-only — never updated or deleted. CREATE TABLE messages ( - id TEXT, -- Unique identifier - account_id TEXT, -- Denormalized for tenant isolation. Auto-set via trigger from conversation.account_id. - -- Array of typed content blocks: text, thinking, tool_use, tool_result - -- JSON array of objects. Each element: - -- $[0].type string - Block type discriminator: text, thinking, tool_use, tool_result - -- $[0].text - Text content (when type=text) - -- $[0].text.content string - Text content - -- $[0].thinking - AI reasoning content (when type=thinking) - -- $[0].thinking.content string - AI reasoning content - -- $[0].tool_use - Tool call (when type=tool_use) - -- $[0].tool_use.id string - Unique tool call identifier - -- $[0].tool_use.name string - Tool name - -- $[0].tool_use.input[] number[] - Tool input parameters as JSON object - -- $[0].tool_result - Tool response (when type=tool_result) - -- $[0].tool_result.tool_use_id string - ID of the tool use this result corresponds to - -- $[0].tool_result.is_error boolean - Whether the tool call failed - -- $[0].tool_result.error string - Human-readable error message (when is_error=true) - -- $[0].tool_result.content[] number[] - Structured result data (when is_error=false) - -- - -- Example: json_extract(content, '$[0].field_name') + id TEXT, + account_id TEXT, content TEXT, - conversation_id TEXT, -- Conversation this message belongs to - created_at TEXT, -- When the message was created - model TEXT, -- AI model that produced this message. Null for user messages. - role TEXT, -- Who sent this message. user: human-originated, assistant: AI-originated. - stop_reason TEXT -- Why the assistant stopped generating. end_turn: completed response, tool_use: paused to call a tool. Null for user messages. + conversation_id TEXT, + created_at TEXT, + model TEXT, + role TEXT, + stop_reason TEXT +); + +CREATE TABLE recommendation_category_statuses_cache ( + id TEXT, + account_id TEXT, + action TEXT, + approved_count INTEGER, + boundary TEXT, + category TEXT, + category_type TEXT, + dismissed_count INTEGER, + display_name TEXT, + estimated_bytes_reduction_per_hour REAL, + estimated_cost_reduction_per_hour_bytes_usd REAL, + estimated_cost_reduction_per_hour_usd REAL, + estimated_cost_reduction_per_hour_volume_usd REAL, + estimated_volume_reduction_per_hour REAL, + events_with_volumes INTEGER, + pending_count INTEGER, + policy_pending_critical_count INTEGER, + policy_pending_high_count INTEGER, + policy_pending_low_count INTEGER, + policy_pending_medium_count INTEGER, + principle TEXT, + subjective INTEGER, + total_event_count INTEGER +); + +CREATE TABLE recommendation_statuses_cache ( + id TEXT, + account_id TEXT, + action TEXT, + approved_at TEXT, + category TEXT, + category_type TEXT, + created_at TEXT, + current_bytes_per_hour REAL, + current_bytes_usd_per_hour REAL, + current_events_per_hour REAL, + current_total_usd_per_hour REAL, + current_volume_usd_per_hour REAL, + dismissed_at TEXT, + estimated_bytes_per_hour REAL, + estimated_bytes_usd_per_hour REAL, + estimated_events_per_hour REAL, + estimated_total_usd_per_hour REAL, + estimated_volume_usd_per_hour REAL, + impact_bytes_per_hour REAL, + impact_bytes_usd_per_hour REAL, + impact_events_per_hour REAL, + impact_total_usd_per_hour REAL, + impact_volume_usd_per_hour REAL, + log_event_id TEXT, + log_event_name TEXT, + recommendation_id TEXT, + service_id TEXT, + service_name TEXT, + severity TEXT, + status TEXT, + subjective INTEGER, + survival_rate REAL, + workspace_id TEXT ); --- Cache table for service_statuses view. Refreshed by cron service. CREATE TABLE service_statuses_cache ( id TEXT, - account_id TEXT, -- Account ID (denormalized from service) - datadog_account_id TEXT, -- The Datadog account performing discovery - estimated_bytes_reduction_per_hour REAL, -- Estimated bytes reduction from active policies - estimated_cost_reduction_per_hour_bytes_usd REAL, -- Estimated bytes-based USD/hour savings from active policies - estimated_cost_reduction_per_hour_usd REAL, -- Estimated total USD/hour savings from active policies - estimated_cost_reduction_per_hour_volume_usd REAL, -- Estimated volume-based USD/hour savings from active policies - estimated_volume_reduction_per_hour REAL, -- Estimated volume reduction from active policies - health TEXT, -- Overall health of the service. DISABLED (integration turned off), INACTIVE (no data received), OK (healthy). - log_event_analyzed_count INTEGER, -- Number of log events that have been analyzed - log_event_bytes_per_hour REAL, -- Discovered log event throughput in bytes/hour from rolling 7-day window - log_event_cost_per_hour_bytes_usd REAL, -- Discovered log event ingestion cost in USD/hour - log_event_cost_per_hour_usd REAL, -- Discovered log event total cost in USD/hour (bytes + volume) - log_event_cost_per_hour_volume_usd REAL, -- Discovered log event indexing cost in USD/hour - log_event_count INTEGER, -- Total number of log events discovered for this service - log_event_volume_per_hour REAL, -- Discovered log event throughput in events/hour from rolling 7-day window - observed_bytes_per_hour_after REAL, -- Measured bytes/hour after policy approval - observed_bytes_per_hour_before REAL, -- Measured bytes/hour before first policy approval - observed_cost_per_hour_after_bytes_usd REAL, -- Measured bytes-based USD/hour cost after approval - observed_cost_per_hour_after_usd REAL, -- Measured total USD/hour cost after approval - observed_cost_per_hour_after_volume_usd REAL, -- Measured volume-based USD/hour cost after approval - observed_cost_per_hour_before_bytes_usd REAL, -- Measured bytes-based USD/hour cost before approval - observed_cost_per_hour_before_usd REAL, -- Measured total USD/hour cost before approval - observed_cost_per_hour_before_volume_usd REAL, -- Measured volume-based USD/hour cost before approval - observed_volume_per_hour_after REAL, -- Measured events/hour after policy approval - observed_volume_per_hour_before REAL, -- Measured events/hour before first policy approval - policy_approved_count INTEGER, -- Policies approved by user - policy_dismissed_count INTEGER, -- Policies dismissed by user - policy_pending_count INTEGER, -- Policies awaiting user action - policy_pending_critical_count INTEGER, -- Pending policies with critical compliance severity - policy_pending_high_count INTEGER, -- Pending policies with high compliance severity - policy_pending_low_count INTEGER, -- Pending policies with low compliance severity - policy_pending_medium_count INTEGER, -- Pending policies with medium compliance severity - service_cost_per_hour_volume_usd REAL, -- Service-level indexing cost in USD/hour based on total service volume - service_debug_volume_per_hour REAL, -- Debug-level events/hour from rolling 7-day window - service_error_volume_per_hour REAL, -- Error-level events/hour from rolling 7-day window - service_id TEXT, -- The service this status belongs to - service_info_volume_per_hour REAL, -- Info-level events/hour from rolling 7-day window - service_other_volume_per_hour REAL, -- Other-level events/hour (trace, fatal, critical, unknown) from rolling 7-day window - service_volume_per_hour REAL, -- Ground-truth service throughput in events/hour from service_log_volumes rolling 7-day window - service_warn_volume_per_hour REAL -- Warn-level events/hour from rolling 7-day window + account_id TEXT, + approved_recommendation_count INTEGER, + current_bytes_per_hour REAL, + current_bytes_usd_per_hour REAL, + current_events_per_hour REAL, + current_service_debug_events_per_hour REAL, + current_service_error_events_per_hour REAL, + current_service_events_per_hour REAL, + current_service_info_events_per_hour REAL, + current_service_other_events_per_hour REAL, + current_service_volume_usd_per_hour REAL, + current_service_warn_events_per_hour REAL, + current_total_usd_per_hour REAL, + current_volume_usd_per_hour REAL, + datadog_account_id TEXT, + dismissed_recommendation_count INTEGER, + estimated_bytes_per_hour REAL, + estimated_bytes_usd_per_hour REAL, + estimated_events_per_hour REAL, + estimated_total_usd_per_hour REAL, + estimated_volume_usd_per_hour REAL, + health TEXT, + impact_bytes_per_hour REAL, + impact_bytes_usd_per_hour REAL, + impact_events_per_hour REAL, + impact_total_usd_per_hour REAL, + impact_volume_usd_per_hour REAL, + log_event_analyzed_count INTEGER, + log_event_count INTEGER, + pending_recommendation_count INTEGER, + policy_pending_critical_count INTEGER, + policy_pending_high_count INTEGER, + policy_pending_low_count INTEGER, + policy_pending_medium_count INTEGER, + recommendation_count INTEGER, + service_id TEXT ); --- Application or microservice that produces logs. Central entity in the data catalog. CREATE TABLE services ( - id TEXT, -- Unique identifier of the service - account_id TEXT, -- Parent account this service belongs to - created_at TEXT, -- When the service was created - description TEXT, -- AI-generated description of what this service does and its telemetry characteristics - enabled INTEGER, -- Whether log analysis and policy generation is active for this service - initial_weekly_log_count INTEGER, -- Approximate weekly log count from initial discovery (7-day period from Datadog) - name TEXT -- Service identifier in telemetry (e.g., 'checkout-service') + id TEXT, + account_id TEXT, + created_at TEXT, + description TEXT, + enabled INTEGER, + initial_weekly_log_count INTEGER, + name TEXT ); --- Group of users within a workspace that reviews policies and manages services CREATE TABLE teams ( - id TEXT, -- Unique identifier of the team - account_id TEXT, -- Denormalized for tenant isolation. Auto-set via trigger from workspace.account_id. - created_at TEXT, -- When the team was created - name TEXT, -- Human-readable name within the workspace - workspace_id TEXT -- Parent workspace this team belongs to + id TEXT, + account_id TEXT, + created_at TEXT, + name TEXT, + workspace_id TEXT ); --- User's saved reference to a view, elevating it from conversation history to their personal collection CREATE TABLE view_favorites ( - id TEXT, -- Unique identifier - account_id TEXT, -- Denormalized for tenant isolation. Auto-set via trigger from view.account_id. - created_at TEXT, -- When the view was favorited - user_id TEXT, -- WorkOS user ID who favorited this view - view_id TEXT -- The view being favorited + id TEXT, + account_id TEXT, + created_at TEXT, + user_id TEXT, + view_id TEXT ); --- Saved SQL query against the local catalog, created by the AI assistant. Immutable — editing creates a fork. CREATE TABLE views ( - id TEXT, -- Unique identifier - account_id TEXT, -- Denormalized for tenant isolation. Auto-set via trigger from message.account_id. - conversation_id TEXT, -- Denormalized from message for easier queries - created_at TEXT, -- When the view was created - created_by TEXT, -- WorkOS user ID who triggered this view creation - entity_type TEXT, -- Which catalog entity this view queries. service: applications, log_event: event patterns, policy: quality recommendations. - forked_from_id TEXT, -- Parent view if this is a refinement/iteration - message_id TEXT, -- Assistant message that created this view via show_view tool call - query TEXT -- Raw SQL query executed against the client's local SQLite database + id TEXT, + account_id TEXT, + conversation_id TEXT, + created_at TEXT, + created_by TEXT, + entity_type TEXT, + forked_from_id TEXT, + message_id TEXT, + query TEXT ); --- Purpose-aligned environment for reviewing and classifying telemetry. Each workspace has its own policies and teams. CREATE TABLE workspaces ( - id TEXT, -- Unique identifier of the workspace - account_id TEXT, -- Parent account this workspace belongs to - created_at TEXT, -- When the workspace was created - name TEXT, -- Human-readable name within the account - purpose TEXT -- Primary purpose determining evaluation strategy. observability: performance and reliability, security: threat detection, compliance: regulatory requirements. + id TEXT, + account_id TEXT, + created_at TEXT, + name TEXT, + purpose TEXT ); - diff --git a/internal/app/onboarding/preflight/preflight_effects.go b/internal/app/onboarding/preflight/preflight_effects.go index 56a7810a..a7ceeb9e 100644 --- a/internal/app/onboarding/preflight/preflight_effects.go +++ b/internal/app/onboarding/preflight/preflight_effects.go @@ -6,6 +6,7 @@ import ( tea "charm.land/bubbletea/v2" + "github.com/usetero/cli/internal/auth" "github.com/usetero/cli/internal/core/bootstrap" "github.com/usetero/cli/internal/domain" ) @@ -13,14 +14,22 @@ import ( func (m *Model) checkAuth() tea.Cmd { return func() tea.Msg { hasValidAuth := false + var user *auth.User if m.auth.IsAuthenticated() { if _, err := m.auth.GetAccessToken(m.ctx); err == nil { hasValidAuth = true + if userID, err := m.auth.GetUserID(m.ctx); err == nil && userID != "" { + user = &auth.User{ID: userID} + } else { + // Avoid getting stuck in sync with a valid token but no user identity. + _ = m.auth.ClearTokens() + hasValidAuth = false + } } else { _ = m.auth.ClearTokens() } } - return preflightAuthCheckCompletedMsg{hasValidAuth: hasValidAuth} + return preflightAuthCheckCompletedMsg{hasValidAuth: hasValidAuth, user: user} } } diff --git a/internal/app/onboarding/preflight/preflight_test.go b/internal/app/onboarding/preflight/preflight_test.go index bb69da3c..bc0221ce 100644 --- a/internal/app/onboarding/preflight/preflight_test.go +++ b/internal/app/onboarding/preflight/preflight_test.go @@ -5,8 +5,13 @@ import ( "errors" "testing" + "github.com/usetero/cli/internal/auth/authtest" + graphql "github.com/usetero/cli/internal/boundary/graphql" "github.com/usetero/cli/internal/core/bootstrap" "github.com/usetero/cli/internal/domain" + "github.com/usetero/cli/internal/log/logtest" + "github.com/usetero/cli/internal/preferences/preferencestest" + "github.com/usetero/cli/internal/styles" ) func TestResolveOrg(t *testing.T) { @@ -70,3 +75,67 @@ func TestPreflightOutcomeForError(t *testing.T) { t.Fatalf("expected inconclusive outcome for generic error, got %v", outcome) } } + +func TestCheckAuthHydratesUserWhenTokenValid(t *testing.T) { + t.Parallel() + + auth := &authtest.MockAuth{ + IsAuthenticatedFunc: func() bool { return true }, + GetAccessTokenFunc: func(context.Context) (string, error) { return "token", nil }, + GetUserIDFunc: func(context.Context) (string, error) { return "user-1", nil }, + } + + m := New( + context.Background(), + styles.NewTheme(true), + graphql.ServiceSet{}, + auth, + preferencestest.NewMockUserPreferences(), + preferencestest.NewMockOrgPreferences(), + logtest.NewScope(t), + ) + + msg := m.checkAuth()().(preflightAuthCheckCompletedMsg) + if !msg.hasValidAuth { + t.Fatal("expected valid auth") + } + if msg.user == nil || msg.user.ID != "user-1" { + t.Fatalf("expected hydrated user id user-1, got %#v", msg.user) + } +} + +func TestCheckAuthClearsInvalidAuthWhenUserIDMissing(t *testing.T) { + t.Parallel() + + cleared := false + auth := &authtest.MockAuth{ + IsAuthenticatedFunc: func() bool { return true }, + GetAccessTokenFunc: func(context.Context) (string, error) { return "token", nil }, + GetUserIDFunc: func(context.Context) (string, error) { return "", errors.New("missing sub") }, + ClearTokensFunc: func() error { + cleared = true + return nil + }, + } + + m := New( + context.Background(), + styles.NewTheme(true), + graphql.ServiceSet{}, + auth, + preferencestest.NewMockUserPreferences(), + preferencestest.NewMockOrgPreferences(), + logtest.NewScope(t), + ) + + msg := m.checkAuth()().(preflightAuthCheckCompletedMsg) + if msg.hasValidAuth { + t.Fatal("expected invalid auth when user id cannot be resolved") + } + if msg.user != nil { + t.Fatalf("expected nil user, got %#v", msg.user) + } + if !cleared { + t.Fatal("expected tokens to be cleared") + } +} diff --git a/internal/app/onboarding/preflight/preflight_types.go b/internal/app/onboarding/preflight/preflight_types.go index eef1e875..e0c57e35 100644 --- a/internal/app/onboarding/preflight/preflight_types.go +++ b/internal/app/onboarding/preflight/preflight_types.go @@ -1,6 +1,7 @@ package preflight import ( + "github.com/usetero/cli/internal/auth" "github.com/usetero/cli/internal/core/bootstrap" "github.com/usetero/cli/internal/domain" ) @@ -11,6 +12,7 @@ type preflightResolutionCompletedMsg struct { type preflightAuthCheckCompletedMsg struct { hasValidAuth bool + user *auth.User } type preflightOrganizationsLoadedMsg struct { diff --git a/internal/app/onboarding/preflight/preflight_update.go b/internal/app/onboarding/preflight/preflight_update.go index 9ad688bf..b1ac51a5 100644 --- a/internal/app/onboarding/preflight/preflight_update.go +++ b/internal/app/onboarding/preflight/preflight_update.go @@ -29,6 +29,7 @@ func (m *Model) Update(msg tea.Msg) tea.Cmd { func (m *Model) handleAuthChecked(msg preflightAuthCheckCompletedMsg) tea.Cmd { m.state.HasValidAuth = msg.hasValidAuth + m.state.User = msg.user if !m.state.HasValidAuth { return m.emitResult() } diff --git a/internal/auth/auth_service.go b/internal/auth/auth_service.go index c9be3f04..3cdffaf9 100644 --- a/internal/auth/auth_service.go +++ b/internal/auth/auth_service.go @@ -200,8 +200,13 @@ func (s *Service) GetAccessToken(ctx context.Context) (string, error) { return "", errors.New("no access token found") } + workosOrgID := domain.WorkosOrganizationID("") + // Check if token is expired claims, err := ParseToken(accessToken) + if err == nil && claims.OrgID != "" { + workosOrgID = domain.WorkosOrganizationID(claims.OrgID) + } if err != nil || claims.IsExpired() { s.scope.Debug("access token expired, refreshing") refreshToken, err := s.storage.Get("refresh_token") @@ -213,7 +218,7 @@ func (s *Service) GetAccessToken(ctx context.Context) (string, error) { return "", errors.New("no refresh token found") } - resp, err := s.provider.RefreshToken(ctx, refreshToken) + resp, err := s.refreshTokenForScope(ctx, refreshToken, workosOrgID) if err != nil { s.scope.Error("failed to refresh token", "error", err) return "", err @@ -237,6 +242,13 @@ func (s *Service) GetAccessToken(ctx context.Context) (string, error) { func (s *Service) ForceRefreshAccessToken(ctx context.Context) (string, error) { s.scope.Debug("force-refreshing access token") + workosOrgID := domain.WorkosOrganizationID("") + if accessToken, err := s.storage.Get("access_token"); err == nil && accessToken != "" { + if claims, parseErr := ParseToken(accessToken); parseErr == nil && claims.OrgID != "" { + workosOrgID = domain.WorkosOrganizationID(claims.OrgID) + } + } + refreshToken, err := s.storage.Get("refresh_token") if err != nil { s.scope.Error("failed to get refresh token", "error", err) @@ -246,7 +258,7 @@ func (s *Service) ForceRefreshAccessToken(ctx context.Context) (string, error) { return "", errors.New("no refresh token found") } - resp, err := s.provider.RefreshToken(ctx, refreshToken) + resp, err := s.refreshTokenForScope(ctx, refreshToken, workosOrgID) if err != nil { s.scope.Error("failed to refresh token", "error", err) return "", err @@ -345,3 +357,11 @@ func (s *Service) saveTokens(accessToken, refreshToken string) error { } return nil } + +func (s *Service) refreshTokenForScope(ctx context.Context, refreshToken string, workosOrgID domain.WorkosOrganizationID) (*RefreshResponse, error) { + if workosOrgID != "" { + s.scope.Debug("refreshing token with preserved organization scope", "workos_org_id", workosOrgID) + return s.provider.RefreshTokenWithOrganization(ctx, refreshToken, workosOrgID) + } + return s.provider.RefreshToken(ctx, refreshToken) +} diff --git a/internal/auth/auth_service_test.go b/internal/auth/auth_service_test.go index 12e2ede6..21e43c55 100644 --- a/internal/auth/auth_service_test.go +++ b/internal/auth/auth_service_test.go @@ -10,6 +10,7 @@ import ( "github.com/usetero/cli/internal/auth" "github.com/usetero/cli/internal/auth/authtest" + "github.com/usetero/cli/internal/domain" "github.com/usetero/cli/internal/log/logtest" ) @@ -108,6 +109,52 @@ func TestService_GetAccessToken(t *testing.T) { t.Fatal("expected error, got nil") } }) + + t.Run("preserves org scope when refreshing expired token", func(t *testing.T) { + t.Parallel() + expiredOrgToken := makeTestTokenWithOrg(time.Now().Add(-10*time.Minute), "org_123") + newToken := makeTestTokenWithOrg(time.Now().Add(10*time.Minute), "org_123") + + storage := &authtest.MockSecureStorage{ + GetFunc: func(key string) (string, error) { + switch key { + case "access_token": + return expiredOrgToken, nil + case "refresh_token": + return "refresh_token_value", nil + } + return "", nil + }, + } + + provider := &authtest.MockOAuthProvider{ + RefreshTokenWithOrganizationFunc: func(ctx context.Context, refreshToken string, organizationID domain.WorkosOrganizationID) (*auth.RefreshResponse, error) { + if refreshToken != "refresh_token_value" { + t.Errorf("unexpected refresh token: %s", refreshToken) + } + if organizationID != "org_123" { + t.Errorf("unexpected organization ID: %s", organizationID) + } + return &auth.RefreshResponse{ + AccessToken: newToken, + RefreshToken: "new_refresh_token", + }, nil + }, + RefreshTokenFunc: func(ctx context.Context, refreshToken string) (*auth.RefreshResponse, error) { + t.Fatal("expected org-scoped refresh path") + return nil, nil + }, + } + + svc := auth.NewService(provider, storage, logtest.NewScope(t)) + token, err := svc.GetAccessToken(context.Background()) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if token != newToken { + t.Errorf("got %q, want %q", token, newToken) + } + }) } func TestService_ForceRefreshAccessToken(t *testing.T) { @@ -218,6 +265,52 @@ func TestService_ForceRefreshAccessToken(t *testing.T) { t.Fatal("expected error, got nil") } }) + + t.Run("preserves org scope on force refresh", func(t *testing.T) { + t.Parallel() + currentOrgToken := makeTestTokenWithOrg(time.Now().Add(10*time.Minute), "org_abc") + newToken := makeTestTokenWithOrg(time.Now().Add(20*time.Minute), "org_abc") + + storage := &authtest.MockSecureStorage{ + GetFunc: func(key string) (string, error) { + switch key { + case "access_token": + return currentOrgToken, nil + case "refresh_token": + return "refresh_token_value", nil + } + return "", nil + }, + } + + provider := &authtest.MockOAuthProvider{ + RefreshTokenWithOrganizationFunc: func(ctx context.Context, refreshToken string, organizationID domain.WorkosOrganizationID) (*auth.RefreshResponse, error) { + if refreshToken != "refresh_token_value" { + t.Errorf("unexpected refresh token: %s", refreshToken) + } + if organizationID != "org_abc" { + t.Errorf("unexpected organization ID: %s", organizationID) + } + return &auth.RefreshResponse{ + AccessToken: newToken, + RefreshToken: "new_refresh_token", + }, nil + }, + RefreshTokenFunc: func(ctx context.Context, refreshToken string) (*auth.RefreshResponse, error) { + t.Fatal("expected org-scoped refresh path") + return nil, nil + }, + } + + svc := auth.NewService(provider, storage, logtest.NewScope(t)) + token, err := svc.ForceRefreshAccessToken(context.Background()) + if err != nil { + t.Fatalf("ForceRefreshAccessToken error: %v", err) + } + if token != newToken { + t.Errorf("got %q, want %q", token, newToken) + } + }) } func TestService_RefreshTokenWithoutOrganization(t *testing.T) { @@ -299,3 +392,14 @@ func makeTestToken(exp time.Time) string { sig := base64.RawURLEncoding.EncodeToString([]byte("signature")) return header + "." + payloadEnc + "." + sig } + +func makeTestTokenWithOrg(exp time.Time, orgID string) string { + header := base64.RawURLEncoding.EncodeToString([]byte(`{"alg":"RS256"}`)) + payload, _ := json.Marshal(map[string]interface{}{ + "exp": exp.Unix(), + "org_id": orgID, + }) + payloadEnc := base64.RawURLEncoding.EncodeToString(payload) + sig := base64.RawURLEncoding.EncodeToString([]byte("signature")) + return header + "." + payloadEnc + "." + sig +} diff --git a/internal/boundary/graphql/apitest/mock_client.go b/internal/boundary/graphql/apitest/mock_client.go index 80f7f0bb..caed4738 100644 --- a/internal/boundary/graphql/apitest/mock_client.go +++ b/internal/boundary/graphql/apitest/mock_client.go @@ -28,8 +28,8 @@ type MockClient struct { CreateMessageFunc func(ctx context.Context, input gen.CreateMessageInput) (*gen.CreateMessageResponse, error) EnableServiceFunc func(ctx context.Context, serviceID string) (*gen.EnableServiceResponse, error) DisableServiceFunc func(ctx context.Context, serviceID string) (*gen.DisableServiceResponse, error) - ApproveLogEventPolicyFunc func(ctx context.Context, policyID string) (*gen.ApproveLogEventPolicyResponse, error) - DismissLogEventPolicyFunc func(ctx context.Context, policyID string) (*gen.DismissLogEventPolicyResponse, error) + ApproveLogEventRecommendationFunc func(ctx context.Context, recommendationID string, targets gen.EnforcementTargetInput) (*gen.ApproveLogEventRecommendationResponse, error) + DismissLogEventRecommendationFunc func(ctx context.Context, recommendationID string) (*gen.DismissLogEventRecommendationResponse, error) } // NewMockClient creates a MockClient with sensible defaults. @@ -165,16 +165,16 @@ func (m *MockClient) DisableService(ctx context.Context, serviceID string) (*gen return nil, nil } -func (m *MockClient) ApproveLogEventPolicy(ctx context.Context, policyID string) (*gen.ApproveLogEventPolicyResponse, error) { - if m.ApproveLogEventPolicyFunc != nil { - return m.ApproveLogEventPolicyFunc(ctx, policyID) +func (m *MockClient) ApproveLogEventRecommendation(ctx context.Context, recommendationID string, targets gen.EnforcementTargetInput) (*gen.ApproveLogEventRecommendationResponse, error) { + if m.ApproveLogEventRecommendationFunc != nil { + return m.ApproveLogEventRecommendationFunc(ctx, recommendationID, targets) } return nil, nil } -func (m *MockClient) DismissLogEventPolicy(ctx context.Context, policyID string) (*gen.DismissLogEventPolicyResponse, error) { - if m.DismissLogEventPolicyFunc != nil { - return m.DismissLogEventPolicyFunc(ctx, policyID) +func (m *MockClient) DismissLogEventRecommendation(ctx context.Context, recommendationID string) (*gen.DismissLogEventRecommendationResponse, error) { + if m.DismissLogEventRecommendationFunc != nil { + return m.DismissLogEventRecommendationFunc(ctx, recommendationID) } return nil, nil } diff --git a/internal/boundary/graphql/client.go b/internal/boundary/graphql/client.go index 4c1646fc..015215a7 100644 --- a/internal/boundary/graphql/client.go +++ b/internal/boundary/graphql/client.go @@ -61,8 +61,8 @@ type Client interface { DisableService(ctx context.Context, serviceID string) (*gen.DisableServiceResponse, error) // Policy operations - ApproveLogEventPolicy(ctx context.Context, policyID string) (*gen.ApproveLogEventPolicyResponse, error) - DismissLogEventPolicy(ctx context.Context, policyID string) (*gen.DismissLogEventPolicyResponse, error) + ApproveLogEventRecommendation(ctx context.Context, recommendationID string, targets gen.EnforcementTargetInput) (*gen.ApproveLogEventRecommendationResponse, error) + DismissLogEventRecommendation(ctx context.Context, recommendationID string) (*gen.DismissLogEventRecommendationResponse, error) } // client is the concrete implementation of Client. @@ -326,18 +326,18 @@ func (c *client) DisableService(ctx context.Context, serviceID string) (*gen.Dis // Policy operations -func (c *client) ApproveLogEventPolicy(ctx context.Context, policyID string) (*gen.ApproveLogEventPolicyResponse, error) { +func (c *client) ApproveLogEventRecommendation(ctx context.Context, recommendationID string, targets gen.EnforcementTargetInput) (*gen.ApproveLogEventRecommendationResponse, error) { gql, err := c.gql(ctx) if err != nil { return nil, err } - return gen.ApproveLogEventPolicy(ctx, gql, policyID) + return gen.ApproveLogEventRecommendation(ctx, gql, recommendationID, targets) } -func (c *client) DismissLogEventPolicy(ctx context.Context, policyID string) (*gen.DismissLogEventPolicyResponse, error) { +func (c *client) DismissLogEventRecommendation(ctx context.Context, recommendationID string) (*gen.DismissLogEventRecommendationResponse, error) { gql, err := c.gql(ctx) if err != nil { return nil, err } - return gen.DismissLogEventPolicy(ctx, gql, policyID) + return gen.DismissLogEventRecommendation(ctx, gql, recommendationID) } diff --git a/internal/boundary/graphql/datadog_account_service.go b/internal/boundary/graphql/datadog_account_service.go index ab90c05a..107e5a48 100644 --- a/internal/boundary/graphql/datadog_account_service.go +++ b/internal/boundary/graphql/datadog_account_service.go @@ -226,9 +226,9 @@ func (s *DatadogAccountService) GetStatus(ctx context.Context, datadogAccountID InactiveServices: statusNode.InactiveServices, EventCount: statusNode.LogEventCount, AnalyzedCount: statusNode.LogEventAnalyzedCount, - PendingPolicyCount: statusNode.PolicyPendingCount, - ApprovedPolicyCount: statusNode.PolicyApprovedCount, - DismissedPolicyCount: statusNode.PolicyDismissedCount, + PendingPolicyCount: statusNode.PendingRecommendationCount, + ApprovedPolicyCount: statusNode.ApprovedRecommendationCount, + DismissedPolicyCount: statusNode.DismissedRecommendationCount, } s.scope.Debug("fetched datadog account status", diff --git a/internal/boundary/graphql/datadog_account_service_test.go b/internal/boundary/graphql/datadog_account_service_test.go index f33d1f1b..b6d53098 100644 --- a/internal/boundary/graphql/datadog_account_service_test.go +++ b/internal/boundary/graphql/datadog_account_service_test.go @@ -292,16 +292,16 @@ func TestDatadogAccountService_GetStatus(t *testing.T) { Node: &gen.GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccount{ Id: "dd-123", Status: &gen.GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache{ - Health: gen.DatadogAccountStatusCacheHealthOk, - ReadyForUse: true, - LogServiceCount: 10, - LogActiveServices: 8, - OkServices: 7, - DisabledServices: 1, - InactiveServices: 1, - LogEventCount: 200, - LogEventAnalyzedCount: 180, - PolicyPendingCount: 12, + Health: gen.DatadogAccountStatusCacheHealthOk, + ReadyForUse: true, + LogServiceCount: 10, + LogActiveServices: 8, + OkServices: 7, + DisabledServices: 1, + InactiveServices: 1, + LogEventCount: 200, + LogEventAnalyzedCount: 180, + PendingRecommendationCount: 12, }, }, }, diff --git a/internal/boundary/graphql/gen/generated.go b/internal/boundary/graphql/gen/generated.go index 6ea4871a..61b913c7 100644 --- a/internal/boundary/graphql/gen/generated.go +++ b/internal/boundary/graphql/gen/generated.go @@ -11,8 +11,8 @@ import ( "github.com/Khan/genqlient/graphql" ) -// ApproveLogEventPolicyApproveLogEventPolicy includes the requested fields of the GraphQL type LogEventPolicy. -type ApproveLogEventPolicyApproveLogEventPolicy struct { +// ApproveLogEventRecommendationApproveLogEventRecommendation includes the requested fields of the GraphQL type LogEventRecommendation. +type ApproveLogEventRecommendationApproveLogEventRecommendation struct { // Unique identifier Id string `json:"id"` // When this policy was approved by a user @@ -25,33 +25,39 @@ type ApproveLogEventPolicyApproveLogEventPolicy struct { DismissedBy *string `json:"dismissedBy"` } -// GetId returns ApproveLogEventPolicyApproveLogEventPolicy.Id, and is useful for accessing the field via an interface. -func (v *ApproveLogEventPolicyApproveLogEventPolicy) GetId() string { return v.Id } +// GetId returns ApproveLogEventRecommendationApproveLogEventRecommendation.Id, and is useful for accessing the field via an interface. +func (v *ApproveLogEventRecommendationApproveLogEventRecommendation) GetId() string { return v.Id } -// GetApprovedAt returns ApproveLogEventPolicyApproveLogEventPolicy.ApprovedAt, and is useful for accessing the field via an interface. -func (v *ApproveLogEventPolicyApproveLogEventPolicy) GetApprovedAt() *time.Time { return v.ApprovedAt } +// GetApprovedAt returns ApproveLogEventRecommendationApproveLogEventRecommendation.ApprovedAt, and is useful for accessing the field via an interface. +func (v *ApproveLogEventRecommendationApproveLogEventRecommendation) GetApprovedAt() *time.Time { + return v.ApprovedAt +} -// GetApprovedBy returns ApproveLogEventPolicyApproveLogEventPolicy.ApprovedBy, and is useful for accessing the field via an interface. -func (v *ApproveLogEventPolicyApproveLogEventPolicy) GetApprovedBy() *string { return v.ApprovedBy } +// GetApprovedBy returns ApproveLogEventRecommendationApproveLogEventRecommendation.ApprovedBy, and is useful for accessing the field via an interface. +func (v *ApproveLogEventRecommendationApproveLogEventRecommendation) GetApprovedBy() *string { + return v.ApprovedBy +} -// GetDismissedAt returns ApproveLogEventPolicyApproveLogEventPolicy.DismissedAt, and is useful for accessing the field via an interface. -func (v *ApproveLogEventPolicyApproveLogEventPolicy) GetDismissedAt() *time.Time { +// GetDismissedAt returns ApproveLogEventRecommendationApproveLogEventRecommendation.DismissedAt, and is useful for accessing the field via an interface. +func (v *ApproveLogEventRecommendationApproveLogEventRecommendation) GetDismissedAt() *time.Time { return v.DismissedAt } -// GetDismissedBy returns ApproveLogEventPolicyApproveLogEventPolicy.DismissedBy, and is useful for accessing the field via an interface. -func (v *ApproveLogEventPolicyApproveLogEventPolicy) GetDismissedBy() *string { return v.DismissedBy } +// GetDismissedBy returns ApproveLogEventRecommendationApproveLogEventRecommendation.DismissedBy, and is useful for accessing the field via an interface. +func (v *ApproveLogEventRecommendationApproveLogEventRecommendation) GetDismissedBy() *string { + return v.DismissedBy +} -// ApproveLogEventPolicyResponse is returned by ApproveLogEventPolicy on success. -type ApproveLogEventPolicyResponse struct { +// ApproveLogEventRecommendationResponse is returned by ApproveLogEventRecommendation on success. +type ApproveLogEventRecommendationResponse struct { // Approve a log event policy, enabling it for enforcement. // Clears any previous dismissal. - ApproveLogEventPolicy ApproveLogEventPolicyApproveLogEventPolicy `json:"approveLogEventPolicy"` + ApproveLogEventRecommendation ApproveLogEventRecommendationApproveLogEventRecommendation `json:"approveLogEventRecommendation"` } -// GetApproveLogEventPolicy returns ApproveLogEventPolicyResponse.ApproveLogEventPolicy, and is useful for accessing the field via an interface. -func (v *ApproveLogEventPolicyResponse) GetApproveLogEventPolicy() ApproveLogEventPolicyApproveLogEventPolicy { - return v.ApproveLogEventPolicy +// GetApproveLogEventRecommendation returns ApproveLogEventRecommendationResponse.ApproveLogEventRecommendation, and is useful for accessing the field via an interface. +func (v *ApproveLogEventRecommendationResponse) GetApproveLogEventRecommendation() ApproveLogEventRecommendationApproveLogEventRecommendation { + return v.ApproveLogEventRecommendation } // A content block in a message. Exactly one of the typed fields should be set. @@ -549,6 +555,13 @@ var AllDatadogAccountStatusCacheHealth = []DatadogAccountStatusCacheHealth{ DatadogAccountStatusCacheHealthOk, } +type DatadogTargetInput struct { + AccountIds []string `json:"accountIds"` +} + +// GetAccountIds returns DatadogTargetInput.AccountIds, and is useful for accessing the field via an interface. +func (v *DatadogTargetInput) GetAccountIds() []string { return v.AccountIds } + // DeleteConversationResponse is returned by DeleteConversation on success. type DeleteConversationResponse struct { // Delete a conversation and all its messages. @@ -587,8 +600,8 @@ func (v *DisableServiceUpdateService) GetName() string { return v.Name } // GetEnabled returns DisableServiceUpdateService.Enabled, and is useful for accessing the field via an interface. func (v *DisableServiceUpdateService) GetEnabled() bool { return v.Enabled } -// DismissLogEventPolicyDismissLogEventPolicy includes the requested fields of the GraphQL type LogEventPolicy. -type DismissLogEventPolicyDismissLogEventPolicy struct { +// DismissLogEventRecommendationDismissLogEventRecommendation includes the requested fields of the GraphQL type LogEventRecommendation. +type DismissLogEventRecommendationDismissLogEventRecommendation struct { // Unique identifier Id string `json:"id"` // When this policy was dismissed by a user @@ -601,35 +614,48 @@ type DismissLogEventPolicyDismissLogEventPolicy struct { ApprovedBy *string `json:"approvedBy"` } -// GetId returns DismissLogEventPolicyDismissLogEventPolicy.Id, and is useful for accessing the field via an interface. -func (v *DismissLogEventPolicyDismissLogEventPolicy) GetId() string { return v.Id } +// GetId returns DismissLogEventRecommendationDismissLogEventRecommendation.Id, and is useful for accessing the field via an interface. +func (v *DismissLogEventRecommendationDismissLogEventRecommendation) GetId() string { return v.Id } -// GetDismissedAt returns DismissLogEventPolicyDismissLogEventPolicy.DismissedAt, and is useful for accessing the field via an interface. -func (v *DismissLogEventPolicyDismissLogEventPolicy) GetDismissedAt() *time.Time { +// GetDismissedAt returns DismissLogEventRecommendationDismissLogEventRecommendation.DismissedAt, and is useful for accessing the field via an interface. +func (v *DismissLogEventRecommendationDismissLogEventRecommendation) GetDismissedAt() *time.Time { return v.DismissedAt } -// GetDismissedBy returns DismissLogEventPolicyDismissLogEventPolicy.DismissedBy, and is useful for accessing the field via an interface. -func (v *DismissLogEventPolicyDismissLogEventPolicy) GetDismissedBy() *string { return v.DismissedBy } +// GetDismissedBy returns DismissLogEventRecommendationDismissLogEventRecommendation.DismissedBy, and is useful for accessing the field via an interface. +func (v *DismissLogEventRecommendationDismissLogEventRecommendation) GetDismissedBy() *string { + return v.DismissedBy +} -// GetApprovedAt returns DismissLogEventPolicyDismissLogEventPolicy.ApprovedAt, and is useful for accessing the field via an interface. -func (v *DismissLogEventPolicyDismissLogEventPolicy) GetApprovedAt() *time.Time { return v.ApprovedAt } +// GetApprovedAt returns DismissLogEventRecommendationDismissLogEventRecommendation.ApprovedAt, and is useful for accessing the field via an interface. +func (v *DismissLogEventRecommendationDismissLogEventRecommendation) GetApprovedAt() *time.Time { + return v.ApprovedAt +} -// GetApprovedBy returns DismissLogEventPolicyDismissLogEventPolicy.ApprovedBy, and is useful for accessing the field via an interface. -func (v *DismissLogEventPolicyDismissLogEventPolicy) GetApprovedBy() *string { return v.ApprovedBy } +// GetApprovedBy returns DismissLogEventRecommendationDismissLogEventRecommendation.ApprovedBy, and is useful for accessing the field via an interface. +func (v *DismissLogEventRecommendationDismissLogEventRecommendation) GetApprovedBy() *string { + return v.ApprovedBy +} -// DismissLogEventPolicyResponse is returned by DismissLogEventPolicy on success. -type DismissLogEventPolicyResponse struct { +// DismissLogEventRecommendationResponse is returned by DismissLogEventRecommendation on success. +type DismissLogEventRecommendationResponse struct { // Dismiss a log event policy, hiding it from pending review. // Clears any previous approval. - DismissLogEventPolicy DismissLogEventPolicyDismissLogEventPolicy `json:"dismissLogEventPolicy"` + DismissLogEventRecommendation DismissLogEventRecommendationDismissLogEventRecommendation `json:"dismissLogEventRecommendation"` +} + +// GetDismissLogEventRecommendation returns DismissLogEventRecommendationResponse.DismissLogEventRecommendation, and is useful for accessing the field via an interface. +func (v *DismissLogEventRecommendationResponse) GetDismissLogEventRecommendation() DismissLogEventRecommendationDismissLogEventRecommendation { + return v.DismissLogEventRecommendation } -// GetDismissLogEventPolicy returns DismissLogEventPolicyResponse.DismissLogEventPolicy, and is useful for accessing the field via an interface. -func (v *DismissLogEventPolicyResponse) GetDismissLogEventPolicy() DismissLogEventPolicyDismissLogEventPolicy { - return v.DismissLogEventPolicy +type EdgeTargetInput struct { + ResourceSelectors []ResourceSelectorInput `json:"resourceSelectors"` } +// GetResourceSelectors returns EdgeTargetInput.ResourceSelectors, and is useful for accessing the field via an interface. +func (v *EdgeTargetInput) GetResourceSelectors() []ResourceSelectorInput { return v.ResourceSelectors } + // EnableServiceResponse is returned by EnableService on success. type EnableServiceResponse struct { UpdateService EnableServiceUpdateService `json:"updateService"` @@ -657,6 +683,17 @@ func (v *EnableServiceUpdateService) GetName() string { return v.Name } // GetEnabled returns EnableServiceUpdateService.Enabled, and is useful for accessing the field via an interface. func (v *EnableServiceUpdateService) GetEnabled() bool { return v.Enabled } +type EnforcementTargetInput struct { + Edge *EdgeTargetInput `json:"edge"` + Datadog *DatadogTargetInput `json:"datadog"` +} + +// GetEdge returns EnforcementTargetInput.Edge, and is useful for accessing the field via an interface. +func (v *EnforcementTargetInput) GetEdge() *EdgeTargetInput { return v.Edge } + +// GetDatadog returns EnforcementTargetInput.Datadog, and is useful for accessing the field via an interface. +func (v *EnforcementTargetInput) GetDatadog() *DatadogTargetInput { return v.Datadog } + // GetAccountAccountsAccountConnection includes the requested fields of the GraphQL type AccountConnection. // The GraphQL type's documentation follows. // @@ -769,7 +806,7 @@ func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesData type GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccount struct { // Unique identifier of the Datadog configuration Id string `json:"id"` - // Status of this Datadog account in the discovery pipeline. + // Status of this Datadog account in the catalog pipeline. // Derived from the status of all services discovered from this account. // Returns null if cache has not been populated yet. Status *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache `json:"status"` @@ -787,41 +824,18 @@ func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesData // GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache includes the requested fields of the GraphQL type DatadogAccountStatusCache. type GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache struct { - // Overall health of the Datadog account. DISABLED (integration turned off), INACTIVE (no data received), OK (healthy). - Health DatadogAccountStatusCacheHealth `json:"health"` - ReadyForUse bool `json:"readyForUse"` - LogEventCount int `json:"logEventCount"` - LogEventAnalyzedCount int `json:"logEventAnalyzedCount"` - LogServiceCount int `json:"logServiceCount"` - LogActiveServices int `json:"logActiveServices"` - DisabledServices int `json:"disabledServices"` - InactiveServices int `json:"inactiveServices"` - OkServices int `json:"okServices"` - PolicyPendingCount int `json:"policyPendingCount"` - PolicyApprovedCount int `json:"policyApprovedCount"` - PolicyDismissedCount int `json:"policyDismissedCount"` - ServiceVolumePerHour *float64 `json:"serviceVolumePerHour"` - ServiceCostPerHourVolumeUsd *float64 `json:"serviceCostPerHourVolumeUsd"` - LogEventVolumePerHour *float64 `json:"logEventVolumePerHour"` - LogEventBytesPerHour *float64 `json:"logEventBytesPerHour"` - LogEventCostPerHourBytesUsd *float64 `json:"logEventCostPerHourBytesUsd"` - LogEventCostPerHourVolumeUsd *float64 `json:"logEventCostPerHourVolumeUsd"` - LogEventCostPerHourUsd *float64 `json:"logEventCostPerHourUsd"` - EstimatedVolumeReductionPerHour *float64 `json:"estimatedVolumeReductionPerHour"` - EstimatedBytesReductionPerHour *float64 `json:"estimatedBytesReductionPerHour"` - EstimatedCostReductionPerHourBytesUsd *float64 `json:"estimatedCostReductionPerHourBytesUsd"` - EstimatedCostReductionPerHourVolumeUsd *float64 `json:"estimatedCostReductionPerHourVolumeUsd"` - EstimatedCostReductionPerHourUsd *float64 `json:"estimatedCostReductionPerHourUsd"` - ObservedVolumePerHourBefore *float64 `json:"observedVolumePerHourBefore"` - ObservedVolumePerHourAfter *float64 `json:"observedVolumePerHourAfter"` - ObservedBytesPerHourBefore *float64 `json:"observedBytesPerHourBefore"` - ObservedBytesPerHourAfter *float64 `json:"observedBytesPerHourAfter"` - ObservedCostPerHourBeforeBytesUsd *float64 `json:"observedCostPerHourBeforeBytesUsd"` - ObservedCostPerHourBeforeVolumeUsd *float64 `json:"observedCostPerHourBeforeVolumeUsd"` - ObservedCostPerHourBeforeUsd *float64 `json:"observedCostPerHourBeforeUsd"` - ObservedCostPerHourAfterBytesUsd *float64 `json:"observedCostPerHourAfterBytesUsd"` - ObservedCostPerHourAfterVolumeUsd *float64 `json:"observedCostPerHourAfterVolumeUsd"` - ObservedCostPerHourAfterUsd *float64 `json:"observedCostPerHourAfterUsd"` + Health DatadogAccountStatusCacheHealth `json:"health"` + ReadyForUse bool `json:"readyForUse"` + LogEventCount int `json:"logEventCount"` + LogEventAnalyzedCount int `json:"logEventAnalyzedCount"` + LogServiceCount int `json:"logServiceCount"` + LogActiveServices int `json:"logActiveServices"` + DisabledServices int `json:"disabledServices"` + InactiveServices int `json:"inactiveServices"` + OkServices int `json:"okServices"` + PendingRecommendationCount int `json:"pendingRecommendationCount"` + ApprovedRecommendationCount int `json:"approvedRecommendationCount"` + DismissedRecommendationCount int `json:"dismissedRecommendationCount"` } // GetHealth returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.Health, and is useful for accessing the field via an interface. @@ -869,129 +883,19 @@ func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesData return v.OkServices } -// GetPolicyPendingCount returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.PolicyPendingCount, and is useful for accessing the field via an interface. -func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache) GetPolicyPendingCount() int { - return v.PolicyPendingCount -} - -// GetPolicyApprovedCount returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.PolicyApprovedCount, and is useful for accessing the field via an interface. -func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache) GetPolicyApprovedCount() int { - return v.PolicyApprovedCount -} - -// GetPolicyDismissedCount returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.PolicyDismissedCount, and is useful for accessing the field via an interface. -func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache) GetPolicyDismissedCount() int { - return v.PolicyDismissedCount -} - -// GetServiceVolumePerHour returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.ServiceVolumePerHour, and is useful for accessing the field via an interface. -func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache) GetServiceVolumePerHour() *float64 { - return v.ServiceVolumePerHour -} - -// GetServiceCostPerHourVolumeUsd returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.ServiceCostPerHourVolumeUsd, and is useful for accessing the field via an interface. -func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache) GetServiceCostPerHourVolumeUsd() *float64 { - return v.ServiceCostPerHourVolumeUsd -} - -// GetLogEventVolumePerHour returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.LogEventVolumePerHour, and is useful for accessing the field via an interface. -func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache) GetLogEventVolumePerHour() *float64 { - return v.LogEventVolumePerHour -} - -// GetLogEventBytesPerHour returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.LogEventBytesPerHour, and is useful for accessing the field via an interface. -func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache) GetLogEventBytesPerHour() *float64 { - return v.LogEventBytesPerHour -} - -// GetLogEventCostPerHourBytesUsd returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.LogEventCostPerHourBytesUsd, and is useful for accessing the field via an interface. -func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache) GetLogEventCostPerHourBytesUsd() *float64 { - return v.LogEventCostPerHourBytesUsd -} - -// GetLogEventCostPerHourVolumeUsd returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.LogEventCostPerHourVolumeUsd, and is useful for accessing the field via an interface. -func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache) GetLogEventCostPerHourVolumeUsd() *float64 { - return v.LogEventCostPerHourVolumeUsd -} - -// GetLogEventCostPerHourUsd returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.LogEventCostPerHourUsd, and is useful for accessing the field via an interface. -func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache) GetLogEventCostPerHourUsd() *float64 { - return v.LogEventCostPerHourUsd -} - -// GetEstimatedVolumeReductionPerHour returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.EstimatedVolumeReductionPerHour, and is useful for accessing the field via an interface. -func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache) GetEstimatedVolumeReductionPerHour() *float64 { - return v.EstimatedVolumeReductionPerHour -} - -// GetEstimatedBytesReductionPerHour returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.EstimatedBytesReductionPerHour, and is useful for accessing the field via an interface. -func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache) GetEstimatedBytesReductionPerHour() *float64 { - return v.EstimatedBytesReductionPerHour -} - -// GetEstimatedCostReductionPerHourBytesUsd returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.EstimatedCostReductionPerHourBytesUsd, and is useful for accessing the field via an interface. -func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache) GetEstimatedCostReductionPerHourBytesUsd() *float64 { - return v.EstimatedCostReductionPerHourBytesUsd -} - -// GetEstimatedCostReductionPerHourVolumeUsd returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.EstimatedCostReductionPerHourVolumeUsd, and is useful for accessing the field via an interface. -func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache) GetEstimatedCostReductionPerHourVolumeUsd() *float64 { - return v.EstimatedCostReductionPerHourVolumeUsd -} - -// GetEstimatedCostReductionPerHourUsd returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.EstimatedCostReductionPerHourUsd, and is useful for accessing the field via an interface. -func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache) GetEstimatedCostReductionPerHourUsd() *float64 { - return v.EstimatedCostReductionPerHourUsd -} - -// GetObservedVolumePerHourBefore returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.ObservedVolumePerHourBefore, and is useful for accessing the field via an interface. -func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache) GetObservedVolumePerHourBefore() *float64 { - return v.ObservedVolumePerHourBefore -} - -// GetObservedVolumePerHourAfter returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.ObservedVolumePerHourAfter, and is useful for accessing the field via an interface. -func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache) GetObservedVolumePerHourAfter() *float64 { - return v.ObservedVolumePerHourAfter -} - -// GetObservedBytesPerHourBefore returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.ObservedBytesPerHourBefore, and is useful for accessing the field via an interface. -func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache) GetObservedBytesPerHourBefore() *float64 { - return v.ObservedBytesPerHourBefore -} - -// GetObservedBytesPerHourAfter returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.ObservedBytesPerHourAfter, and is useful for accessing the field via an interface. -func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache) GetObservedBytesPerHourAfter() *float64 { - return v.ObservedBytesPerHourAfter -} - -// GetObservedCostPerHourBeforeBytesUsd returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.ObservedCostPerHourBeforeBytesUsd, and is useful for accessing the field via an interface. -func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache) GetObservedCostPerHourBeforeBytesUsd() *float64 { - return v.ObservedCostPerHourBeforeBytesUsd -} - -// GetObservedCostPerHourBeforeVolumeUsd returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.ObservedCostPerHourBeforeVolumeUsd, and is useful for accessing the field via an interface. -func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache) GetObservedCostPerHourBeforeVolumeUsd() *float64 { - return v.ObservedCostPerHourBeforeVolumeUsd -} - -// GetObservedCostPerHourBeforeUsd returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.ObservedCostPerHourBeforeUsd, and is useful for accessing the field via an interface. -func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache) GetObservedCostPerHourBeforeUsd() *float64 { - return v.ObservedCostPerHourBeforeUsd -} - -// GetObservedCostPerHourAfterBytesUsd returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.ObservedCostPerHourAfterBytesUsd, and is useful for accessing the field via an interface. -func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache) GetObservedCostPerHourAfterBytesUsd() *float64 { - return v.ObservedCostPerHourAfterBytesUsd +// GetPendingRecommendationCount returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.PendingRecommendationCount, and is useful for accessing the field via an interface. +func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache) GetPendingRecommendationCount() int { + return v.PendingRecommendationCount } -// GetObservedCostPerHourAfterVolumeUsd returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.ObservedCostPerHourAfterVolumeUsd, and is useful for accessing the field via an interface. -func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache) GetObservedCostPerHourAfterVolumeUsd() *float64 { - return v.ObservedCostPerHourAfterVolumeUsd +// GetApprovedRecommendationCount returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.ApprovedRecommendationCount, and is useful for accessing the field via an interface. +func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache) GetApprovedRecommendationCount() int { + return v.ApprovedRecommendationCount } -// GetObservedCostPerHourAfterUsd returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.ObservedCostPerHourAfterUsd, and is useful for accessing the field via an interface. -func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache) GetObservedCostPerHourAfterUsd() *float64 { - return v.ObservedCostPerHourAfterUsd +// GetDismissedRecommendationCount returns GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache.DismissedRecommendationCount, and is useful for accessing the field via an interface. +func (v *GetDatadogAccountStatusDatadogAccountsDatadogAccountConnectionEdgesDatadogAccountEdgeNodeDatadogAccountStatusDatadogAccountStatusCache) GetDismissedRecommendationCount() int { + return v.DismissedRecommendationCount } // GetDatadogAccountStatusResponse is returned by GetDatadogAccountStatus on success. @@ -1101,16 +1005,21 @@ func (v *GetServiceByNameServicesServiceConnectionEdgesServiceEdgeNodeService) G // GetServiceNodeDatadogLogIndex // GetServiceNodeEdgeApiKey // GetServiceNodeEdgeInstance +// GetServiceNodeFinding // GetServiceNodeLogEvent +// GetServiceNodeLogEventFact // GetServiceNodeLogEventField -// GetServiceNodeLogEventPolicy -// GetServiceNodeLogEventPolicyCategoryStatusCache -// GetServiceNodeLogEventPolicyStatusCache +// GetServiceNodeLogEventFieldFact +// GetServiceNodeLogEventRecommendation +// GetServiceNodeLogEventRecommendationCategoryStatusCache +// GetServiceNodeLogEventRecommendationStatusCache // GetServiceNodeLogEventStatusCache // GetServiceNodeLogSample // GetServiceNodeMessage // GetServiceNodeOrganization // GetServiceNodeService +// GetServiceNodeServiceLogField +// GetServiceNodeServiceLogFieldFact // GetServiceNodeServiceStatusCache // GetServiceNodeTeam // GetServiceNodeView @@ -1134,22 +1043,28 @@ func (v *GetServiceNodeDatadogAccountStatusCache) implementsGraphQLInterfaceGetS func (v *GetServiceNodeDatadogLogIndex) implementsGraphQLInterfaceGetServiceNode() {} func (v *GetServiceNodeEdgeApiKey) implementsGraphQLInterfaceGetServiceNode() {} func (v *GetServiceNodeEdgeInstance) implementsGraphQLInterfaceGetServiceNode() {} +func (v *GetServiceNodeFinding) implementsGraphQLInterfaceGetServiceNode() {} func (v *GetServiceNodeLogEvent) implementsGraphQLInterfaceGetServiceNode() {} +func (v *GetServiceNodeLogEventFact) implementsGraphQLInterfaceGetServiceNode() {} func (v *GetServiceNodeLogEventField) implementsGraphQLInterfaceGetServiceNode() {} -func (v *GetServiceNodeLogEventPolicy) implementsGraphQLInterfaceGetServiceNode() {} -func (v *GetServiceNodeLogEventPolicyCategoryStatusCache) implementsGraphQLInterfaceGetServiceNode() { -} -func (v *GetServiceNodeLogEventPolicyStatusCache) implementsGraphQLInterfaceGetServiceNode() {} -func (v *GetServiceNodeLogEventStatusCache) implementsGraphQLInterfaceGetServiceNode() {} -func (v *GetServiceNodeLogSample) implementsGraphQLInterfaceGetServiceNode() {} -func (v *GetServiceNodeMessage) implementsGraphQLInterfaceGetServiceNode() {} -func (v *GetServiceNodeOrganization) implementsGraphQLInterfaceGetServiceNode() {} -func (v *GetServiceNodeService) implementsGraphQLInterfaceGetServiceNode() {} -func (v *GetServiceNodeServiceStatusCache) implementsGraphQLInterfaceGetServiceNode() {} -func (v *GetServiceNodeTeam) implementsGraphQLInterfaceGetServiceNode() {} -func (v *GetServiceNodeView) implementsGraphQLInterfaceGetServiceNode() {} -func (v *GetServiceNodeViewFavorite) implementsGraphQLInterfaceGetServiceNode() {} -func (v *GetServiceNodeWorkspace) implementsGraphQLInterfaceGetServiceNode() {} +func (v *GetServiceNodeLogEventFieldFact) implementsGraphQLInterfaceGetServiceNode() {} +func (v *GetServiceNodeLogEventRecommendation) implementsGraphQLInterfaceGetServiceNode() {} +func (v *GetServiceNodeLogEventRecommendationCategoryStatusCache) implementsGraphQLInterfaceGetServiceNode() { +} +func (v *GetServiceNodeLogEventRecommendationStatusCache) implementsGraphQLInterfaceGetServiceNode() { +} +func (v *GetServiceNodeLogEventStatusCache) implementsGraphQLInterfaceGetServiceNode() {} +func (v *GetServiceNodeLogSample) implementsGraphQLInterfaceGetServiceNode() {} +func (v *GetServiceNodeMessage) implementsGraphQLInterfaceGetServiceNode() {} +func (v *GetServiceNodeOrganization) implementsGraphQLInterfaceGetServiceNode() {} +func (v *GetServiceNodeService) implementsGraphQLInterfaceGetServiceNode() {} +func (v *GetServiceNodeServiceLogField) implementsGraphQLInterfaceGetServiceNode() {} +func (v *GetServiceNodeServiceLogFieldFact) implementsGraphQLInterfaceGetServiceNode() {} +func (v *GetServiceNodeServiceStatusCache) implementsGraphQLInterfaceGetServiceNode() {} +func (v *GetServiceNodeTeam) implementsGraphQLInterfaceGetServiceNode() {} +func (v *GetServiceNodeView) implementsGraphQLInterfaceGetServiceNode() {} +func (v *GetServiceNodeViewFavorite) implementsGraphQLInterfaceGetServiceNode() {} +func (v *GetServiceNodeWorkspace) implementsGraphQLInterfaceGetServiceNode() {} func __unmarshalGetServiceNode(b []byte, v *GetServiceNode) error { if string(b) == "null" { @@ -1189,20 +1104,29 @@ func __unmarshalGetServiceNode(b []byte, v *GetServiceNode) error { case "EdgeInstance": *v = new(GetServiceNodeEdgeInstance) return json.Unmarshal(b, *v) + case "Finding": + *v = new(GetServiceNodeFinding) + return json.Unmarshal(b, *v) case "LogEvent": *v = new(GetServiceNodeLogEvent) return json.Unmarshal(b, *v) + case "LogEventFact": + *v = new(GetServiceNodeLogEventFact) + return json.Unmarshal(b, *v) case "LogEventField": *v = new(GetServiceNodeLogEventField) return json.Unmarshal(b, *v) - case "LogEventPolicy": - *v = new(GetServiceNodeLogEventPolicy) + case "LogEventFieldFact": + *v = new(GetServiceNodeLogEventFieldFact) + return json.Unmarshal(b, *v) + case "LogEventRecommendation": + *v = new(GetServiceNodeLogEventRecommendation) return json.Unmarshal(b, *v) - case "LogEventPolicyCategoryStatusCache": - *v = new(GetServiceNodeLogEventPolicyCategoryStatusCache) + case "LogEventRecommendationCategoryStatusCache": + *v = new(GetServiceNodeLogEventRecommendationCategoryStatusCache) return json.Unmarshal(b, *v) - case "LogEventPolicyStatusCache": - *v = new(GetServiceNodeLogEventPolicyStatusCache) + case "LogEventRecommendationStatusCache": + *v = new(GetServiceNodeLogEventRecommendationStatusCache) return json.Unmarshal(b, *v) case "LogEventStatusCache": *v = new(GetServiceNodeLogEventStatusCache) @@ -1219,6 +1143,12 @@ func __unmarshalGetServiceNode(b []byte, v *GetServiceNode) error { case "Service": *v = new(GetServiceNodeService) return json.Unmarshal(b, *v) + case "ServiceLogField": + *v = new(GetServiceNodeServiceLogField) + return json.Unmarshal(b, *v) + case "ServiceLogFieldFact": + *v = new(GetServiceNodeServiceLogFieldFact) + return json.Unmarshal(b, *v) case "ServiceStatusCache": *v = new(GetServiceNodeServiceStatusCache) return json.Unmarshal(b, *v) @@ -1311,6 +1241,14 @@ func __marshalGetServiceNode(v *GetServiceNode) ([]byte, error) { *GetServiceNodeEdgeInstance }{typename, v} return json.Marshal(result) + case *GetServiceNodeFinding: + typename = "Finding" + + result := struct { + TypeName string `json:"__typename"` + *GetServiceNodeFinding + }{typename, v} + return json.Marshal(result) case *GetServiceNodeLogEvent: typename = "LogEvent" @@ -1319,6 +1257,14 @@ func __marshalGetServiceNode(v *GetServiceNode) ([]byte, error) { *GetServiceNodeLogEvent }{typename, v} return json.Marshal(result) + case *GetServiceNodeLogEventFact: + typename = "LogEventFact" + + result := struct { + TypeName string `json:"__typename"` + *GetServiceNodeLogEventFact + }{typename, v} + return json.Marshal(result) case *GetServiceNodeLogEventField: typename = "LogEventField" @@ -1327,28 +1273,36 @@ func __marshalGetServiceNode(v *GetServiceNode) ([]byte, error) { *GetServiceNodeLogEventField }{typename, v} return json.Marshal(result) - case *GetServiceNodeLogEventPolicy: - typename = "LogEventPolicy" + case *GetServiceNodeLogEventFieldFact: + typename = "LogEventFieldFact" + + result := struct { + TypeName string `json:"__typename"` + *GetServiceNodeLogEventFieldFact + }{typename, v} + return json.Marshal(result) + case *GetServiceNodeLogEventRecommendation: + typename = "LogEventRecommendation" result := struct { TypeName string `json:"__typename"` - *GetServiceNodeLogEventPolicy + *GetServiceNodeLogEventRecommendation }{typename, v} return json.Marshal(result) - case *GetServiceNodeLogEventPolicyCategoryStatusCache: - typename = "LogEventPolicyCategoryStatusCache" + case *GetServiceNodeLogEventRecommendationCategoryStatusCache: + typename = "LogEventRecommendationCategoryStatusCache" result := struct { TypeName string `json:"__typename"` - *GetServiceNodeLogEventPolicyCategoryStatusCache + *GetServiceNodeLogEventRecommendationCategoryStatusCache }{typename, v} return json.Marshal(result) - case *GetServiceNodeLogEventPolicyStatusCache: - typename = "LogEventPolicyStatusCache" + case *GetServiceNodeLogEventRecommendationStatusCache: + typename = "LogEventRecommendationStatusCache" result := struct { TypeName string `json:"__typename"` - *GetServiceNodeLogEventPolicyStatusCache + *GetServiceNodeLogEventRecommendationStatusCache }{typename, v} return json.Marshal(result) case *GetServiceNodeLogEventStatusCache: @@ -1391,6 +1345,22 @@ func __marshalGetServiceNode(v *GetServiceNode) ([]byte, error) { *GetServiceNodeService }{typename, v} return json.Marshal(result) + case *GetServiceNodeServiceLogField: + typename = "ServiceLogField" + + result := struct { + TypeName string `json:"__typename"` + *GetServiceNodeServiceLogField + }{typename, v} + return json.Marshal(result) + case *GetServiceNodeServiceLogFieldFact: + typename = "ServiceLogFieldFact" + + result := struct { + TypeName string `json:"__typename"` + *GetServiceNodeServiceLogFieldFact + }{typename, v} + return json.Marshal(result) case *GetServiceNodeServiceStatusCache: typename = "ServiceStatusCache" @@ -1503,6 +1473,14 @@ type GetServiceNodeEdgeInstance struct { // GetTypename returns GetServiceNodeEdgeInstance.Typename, and is useful for accessing the field via an interface. func (v *GetServiceNodeEdgeInstance) GetTypename() *string { return v.Typename } +// GetServiceNodeFinding includes the requested fields of the GraphQL type Finding. +type GetServiceNodeFinding struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns GetServiceNodeFinding.Typename, and is useful for accessing the field via an interface. +func (v *GetServiceNodeFinding) GetTypename() *string { return v.Typename } + // GetServiceNodeLogEvent includes the requested fields of the GraphQL type LogEvent. type GetServiceNodeLogEvent struct { Typename *string `json:"__typename"` @@ -1511,6 +1489,14 @@ type GetServiceNodeLogEvent struct { // GetTypename returns GetServiceNodeLogEvent.Typename, and is useful for accessing the field via an interface. func (v *GetServiceNodeLogEvent) GetTypename() *string { return v.Typename } +// GetServiceNodeLogEventFact includes the requested fields of the GraphQL type LogEventFact. +type GetServiceNodeLogEventFact struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns GetServiceNodeLogEventFact.Typename, and is useful for accessing the field via an interface. +func (v *GetServiceNodeLogEventFact) GetTypename() *string { return v.Typename } + // GetServiceNodeLogEventField includes the requested fields of the GraphQL type LogEventField. type GetServiceNodeLogEventField struct { Typename *string `json:"__typename"` @@ -1519,29 +1505,39 @@ type GetServiceNodeLogEventField struct { // GetTypename returns GetServiceNodeLogEventField.Typename, and is useful for accessing the field via an interface. func (v *GetServiceNodeLogEventField) GetTypename() *string { return v.Typename } -// GetServiceNodeLogEventPolicy includes the requested fields of the GraphQL type LogEventPolicy. -type GetServiceNodeLogEventPolicy struct { +// GetServiceNodeLogEventFieldFact includes the requested fields of the GraphQL type LogEventFieldFact. +type GetServiceNodeLogEventFieldFact struct { Typename *string `json:"__typename"` } -// GetTypename returns GetServiceNodeLogEventPolicy.Typename, and is useful for accessing the field via an interface. -func (v *GetServiceNodeLogEventPolicy) GetTypename() *string { return v.Typename } +// GetTypename returns GetServiceNodeLogEventFieldFact.Typename, and is useful for accessing the field via an interface. +func (v *GetServiceNodeLogEventFieldFact) GetTypename() *string { return v.Typename } -// GetServiceNodeLogEventPolicyCategoryStatusCache includes the requested fields of the GraphQL type LogEventPolicyCategoryStatusCache. -type GetServiceNodeLogEventPolicyCategoryStatusCache struct { +// GetServiceNodeLogEventRecommendation includes the requested fields of the GraphQL type LogEventRecommendation. +type GetServiceNodeLogEventRecommendation struct { Typename *string `json:"__typename"` } -// GetTypename returns GetServiceNodeLogEventPolicyCategoryStatusCache.Typename, and is useful for accessing the field via an interface. -func (v *GetServiceNodeLogEventPolicyCategoryStatusCache) GetTypename() *string { return v.Typename } +// GetTypename returns GetServiceNodeLogEventRecommendation.Typename, and is useful for accessing the field via an interface. +func (v *GetServiceNodeLogEventRecommendation) GetTypename() *string { return v.Typename } -// GetServiceNodeLogEventPolicyStatusCache includes the requested fields of the GraphQL type LogEventPolicyStatusCache. -type GetServiceNodeLogEventPolicyStatusCache struct { +// GetServiceNodeLogEventRecommendationCategoryStatusCache includes the requested fields of the GraphQL type LogEventRecommendationCategoryStatusCache. +type GetServiceNodeLogEventRecommendationCategoryStatusCache struct { Typename *string `json:"__typename"` } -// GetTypename returns GetServiceNodeLogEventPolicyStatusCache.Typename, and is useful for accessing the field via an interface. -func (v *GetServiceNodeLogEventPolicyStatusCache) GetTypename() *string { return v.Typename } +// GetTypename returns GetServiceNodeLogEventRecommendationCategoryStatusCache.Typename, and is useful for accessing the field via an interface. +func (v *GetServiceNodeLogEventRecommendationCategoryStatusCache) GetTypename() *string { + return v.Typename +} + +// GetServiceNodeLogEventRecommendationStatusCache includes the requested fields of the GraphQL type LogEventRecommendationStatusCache. +type GetServiceNodeLogEventRecommendationStatusCache struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns GetServiceNodeLogEventRecommendationStatusCache.Typename, and is useful for accessing the field via an interface. +func (v *GetServiceNodeLogEventRecommendationStatusCache) GetTypename() *string { return v.Typename } // GetServiceNodeLogEventStatusCache includes the requested fields of the GraphQL type LogEventStatusCache. type GetServiceNodeLogEventStatusCache struct { @@ -1663,6 +1659,22 @@ func (v *GetServiceNodeServiceLogEventsLogEvent) GetDescription() string { retur // GetCreatedAt returns GetServiceNodeServiceLogEventsLogEvent.CreatedAt, and is useful for accessing the field via an interface. func (v *GetServiceNodeServiceLogEventsLogEvent) GetCreatedAt() time.Time { return v.CreatedAt } +// GetServiceNodeServiceLogField includes the requested fields of the GraphQL type ServiceLogField. +type GetServiceNodeServiceLogField struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns GetServiceNodeServiceLogField.Typename, and is useful for accessing the field via an interface. +func (v *GetServiceNodeServiceLogField) GetTypename() *string { return v.Typename } + +// GetServiceNodeServiceLogFieldFact includes the requested fields of the GraphQL type ServiceLogFieldFact. +type GetServiceNodeServiceLogFieldFact struct { + Typename *string `json:"__typename"` +} + +// GetTypename returns GetServiceNodeServiceLogFieldFact.Typename, and is useful for accessing the field via an interface. +func (v *GetServiceNodeServiceLogFieldFact) GetTypename() *string { return v.Typename } + // GetServiceNodeServiceStatusCache includes the requested fields of the GraphQL type ServiceStatusCache. type GetServiceNodeServiceStatusCache struct { Typename *string `json:"__typename"` @@ -2114,6 +2126,17 @@ var AllMessageStopReason = []MessageStopReason{ MessageStopReasonToolUse, } +type ResourceSelectorInput struct { + Key string `json:"key"` + Value string `json:"value"` +} + +// GetKey returns ResourceSelectorInput.Key, and is useful for accessing the field via an interface. +func (v *ResourceSelectorInput) GetKey() string { return v.Key } + +// GetValue returns ResourceSelectorInput.Value, and is useful for accessing the field via an interface. +func (v *ResourceSelectorInput) GetValue() string { return v.Value } + // Text content from the user or assistant. type TextBlockInput struct { Content string `json:"content"` @@ -2277,13 +2300,17 @@ var AllWorkspacePurpose = []WorkspacePurpose{ WorkspacePurposeCompliance, } -// __ApproveLogEventPolicyInput is used internally by genqlient -type __ApproveLogEventPolicyInput struct { - Id string `json:"id"` +// __ApproveLogEventRecommendationInput is used internally by genqlient +type __ApproveLogEventRecommendationInput struct { + Id string `json:"id"` + Targets EnforcementTargetInput `json:"targets"` } -// GetId returns __ApproveLogEventPolicyInput.Id, and is useful for accessing the field via an interface. -func (v *__ApproveLogEventPolicyInput) GetId() string { return v.Id } +// GetId returns __ApproveLogEventRecommendationInput.Id, and is useful for accessing the field via an interface. +func (v *__ApproveLogEventRecommendationInput) GetId() string { return v.Id } + +// GetTargets returns __ApproveLogEventRecommendationInput.Targets, and is useful for accessing the field via an interface. +func (v *__ApproveLogEventRecommendationInput) GetTargets() EnforcementTargetInput { return v.Targets } // __CreateAccountInput is used internally by genqlient type __CreateAccountInput struct { @@ -2343,13 +2370,13 @@ type __DisableServiceInput struct { // GetServiceId returns __DisableServiceInput.ServiceId, and is useful for accessing the field via an interface. func (v *__DisableServiceInput) GetServiceId() string { return v.ServiceId } -// __DismissLogEventPolicyInput is used internally by genqlient -type __DismissLogEventPolicyInput struct { +// __DismissLogEventRecommendationInput is used internally by genqlient +type __DismissLogEventRecommendationInput struct { Id string `json:"id"` } -// GetId returns __DismissLogEventPolicyInput.Id, and is useful for accessing the field via an interface. -func (v *__DismissLogEventPolicyInput) GetId() string { return v.Id } +// GetId returns __DismissLogEventRecommendationInput.Id, and is useful for accessing the field via an interface. +func (v *__DismissLogEventRecommendationInput) GetId() string { return v.Id } // __EnableServiceInput is used internally by genqlient type __EnableServiceInput struct { @@ -2427,10 +2454,10 @@ type __ValidateDatadogApiKeyInput struct { // GetInput returns __ValidateDatadogApiKeyInput.Input, and is useful for accessing the field via an interface. func (v *__ValidateDatadogApiKeyInput) GetInput() ValidateDatadogApiKeyInput { return v.Input } -// The mutation executed by ApproveLogEventPolicy. -const ApproveLogEventPolicy_Operation = ` -mutation ApproveLogEventPolicy ($id: ID!) { - approveLogEventPolicy(id: $id) { +// The mutation executed by ApproveLogEventRecommendation. +const ApproveLogEventRecommendation_Operation = ` +mutation ApproveLogEventRecommendation ($id: ID!, $targets: EnforcementTargetInput!) { + approveLogEventRecommendation(id: $id, targets: $targets) { id approvedAt approvedBy @@ -2440,21 +2467,23 @@ mutation ApproveLogEventPolicy ($id: ID!) { } ` -// Mutation to approve a log event policy for enforcement -func ApproveLogEventPolicy( +// Mutation to approve a log event recommendation for enforcement +func ApproveLogEventRecommendation( ctx_ context.Context, client_ graphql.Client, id string, -) (data_ *ApproveLogEventPolicyResponse, err_ error) { + targets EnforcementTargetInput, +) (data_ *ApproveLogEventRecommendationResponse, err_ error) { req_ := &graphql.Request{ - OpName: "ApproveLogEventPolicy", - Query: ApproveLogEventPolicy_Operation, - Variables: &__ApproveLogEventPolicyInput{ - Id: id, + OpName: "ApproveLogEventRecommendation", + Query: ApproveLogEventRecommendation_Operation, + Variables: &__ApproveLogEventRecommendationInput{ + Id: id, + Targets: targets, }, } - data_ = &ApproveLogEventPolicyResponse{} + data_ = &ApproveLogEventRecommendationResponse{} resp_ := &graphql.Response{Data: data_} err_ = client_.MakeRequest( @@ -2731,10 +2760,10 @@ func DisableService( return data_, err_ } -// The mutation executed by DismissLogEventPolicy. -const DismissLogEventPolicy_Operation = ` -mutation DismissLogEventPolicy ($id: ID!) { - dismissLogEventPolicy(id: $id) { +// The mutation executed by DismissLogEventRecommendation. +const DismissLogEventRecommendation_Operation = ` +mutation DismissLogEventRecommendation ($id: ID!) { + dismissLogEventRecommendation(id: $id) { id dismissedAt dismissedBy @@ -2744,21 +2773,21 @@ mutation DismissLogEventPolicy ($id: ID!) { } ` -// Mutation to dismiss a log event policy from pending review -func DismissLogEventPolicy( +// Mutation to dismiss a log event recommendation from pending review +func DismissLogEventRecommendation( ctx_ context.Context, client_ graphql.Client, id string, -) (data_ *DismissLogEventPolicyResponse, err_ error) { +) (data_ *DismissLogEventRecommendationResponse, err_ error) { req_ := &graphql.Request{ - OpName: "DismissLogEventPolicy", - Query: DismissLogEventPolicy_Operation, - Variables: &__DismissLogEventPolicyInput{ + OpName: "DismissLogEventRecommendation", + Query: DismissLogEventRecommendation_Operation, + Variables: &__DismissLogEventRecommendationInput{ Id: id, }, } - data_ = &DismissLogEventPolicyResponse{} + data_ = &DismissLogEventRecommendationResponse{} resp_ := &graphql.Response{Data: data_} err_ = client_.MakeRequest( @@ -2867,31 +2896,9 @@ query GetDatadogAccountStatus ($id: ID!) { disabledServices inactiveServices okServices - policyPendingCount - policyApprovedCount - policyDismissedCount - serviceVolumePerHour - serviceCostPerHourVolumeUsd - logEventVolumePerHour - logEventBytesPerHour - logEventCostPerHourBytesUsd - logEventCostPerHourVolumeUsd - logEventCostPerHourUsd - estimatedVolumeReductionPerHour - estimatedBytesReductionPerHour - estimatedCostReductionPerHourBytesUsd - estimatedCostReductionPerHourVolumeUsd - estimatedCostReductionPerHourUsd - observedVolumePerHourBefore - observedVolumePerHourAfter - observedBytesPerHourBefore - observedBytesPerHourAfter - observedCostPerHourBeforeBytesUsd - observedCostPerHourBeforeVolumeUsd - observedCostPerHourBeforeUsd - observedCostPerHourAfterBytesUsd - observedCostPerHourAfterVolumeUsd - observedCostPerHourAfterUsd + pendingRecommendationCount + approvedRecommendationCount + dismissedRecommendationCount } } } diff --git a/internal/boundary/graphql/gen/queries/datadog_accounts.graphql b/internal/boundary/graphql/gen/queries/datadog_accounts.graphql index 9a732fac..26fc3eaa 100644 --- a/internal/boundary/graphql/gen/queries/datadog_accounts.graphql +++ b/internal/boundary/graphql/gen/queries/datadog_accounts.graphql @@ -47,31 +47,9 @@ query GetDatadogAccountStatus($id: ID!) { disabledServices inactiveServices okServices - policyPendingCount - policyApprovedCount - policyDismissedCount - serviceVolumePerHour - serviceCostPerHourVolumeUsd - logEventVolumePerHour - logEventBytesPerHour - logEventCostPerHourBytesUsd - logEventCostPerHourVolumeUsd - logEventCostPerHourUsd - estimatedVolumeReductionPerHour - estimatedBytesReductionPerHour - estimatedCostReductionPerHourBytesUsd - estimatedCostReductionPerHourVolumeUsd - estimatedCostReductionPerHourUsd - observedVolumePerHourBefore - observedVolumePerHourAfter - observedBytesPerHourBefore - observedBytesPerHourAfter - observedCostPerHourBeforeBytesUsd - observedCostPerHourBeforeVolumeUsd - observedCostPerHourBeforeUsd - observedCostPerHourAfterBytesUsd - observedCostPerHourAfterVolumeUsd - observedCostPerHourAfterUsd + pendingRecommendationCount + approvedRecommendationCount + dismissedRecommendationCount } } } diff --git a/internal/boundary/graphql/gen/queries/log_event_policies.graphql b/internal/boundary/graphql/gen/queries/log_event_policies.graphql index 942289aa..b1e3afa4 100644 --- a/internal/boundary/graphql/gen/queries/log_event_policies.graphql +++ b/internal/boundary/graphql/gen/queries/log_event_policies.graphql @@ -1,21 +1,21 @@ -# Mutation to approve a log event policy for enforcement -mutation ApproveLogEventPolicy($id: ID!) { - approveLogEventPolicy(id: $id) { - id - approvedAt - approvedBy - dismissedAt - dismissedBy - } +# Mutation to approve a log event recommendation for enforcement +mutation ApproveLogEventRecommendation($id: ID!, $targets: EnforcementTargetInput!) { + approveLogEventRecommendation(id: $id, targets: $targets) { + id + approvedAt + approvedBy + dismissedAt + dismissedBy + } } -# Mutation to dismiss a log event policy from pending review -mutation DismissLogEventPolicy($id: ID!) { - dismissLogEventPolicy(id: $id) { - id - dismissedAt - dismissedBy - approvedAt - approvedBy - } +# Mutation to dismiss a log event recommendation from pending review +mutation DismissLogEventRecommendation($id: ID!) { + dismissLogEventRecommendation(id: $id) { + id + dismissedAt + dismissedBy + approvedAt + approvedBy + } } diff --git a/internal/boundary/graphql/gen/schema.graphql b/internal/boundary/graphql/gen/schema.graphql index 809b1854..8bd67545 100644 --- a/internal/boundary/graphql/gen/schema.graphql +++ b/internal/boundary/graphql/gen/schema.graphql @@ -865,7 +865,7 @@ type DatadogAccount implements Node { logIndexes: [DatadogLogIndex!] """ - Status of this Datadog account in the discovery pipeline. + Status of this Datadog account in the catalog pipeline. Derived from the status of all services discovered from this account. Returns null if cache has not been populated yet. """ @@ -926,10 +926,6 @@ type DatadogAccountStatusCache implements Node { id: ID! datadogAccountID: ID! accountID: UUID! - - """ - Overall health of the Datadog account. DISABLED (integration turned off), INACTIVE (no data received), OK (healthy). - """ health: DatadogAccountStatusCacheHealth! readyForUse: Boolean! logEventAnalyzedCount: Int! @@ -939,35 +935,31 @@ type DatadogAccountStatusCache implements Node { inactiveServices: Int! okServices: Int! logEventCount: Int! - policyPendingCount: Int! - policyApprovedCount: Int! - policyDismissedCount: Int! + recommendationCount: Int! + pendingRecommendationCount: Int! + approvedRecommendationCount: Int! + dismissedRecommendationCount: Int! policyPendingLowCount: Int! policyPendingMediumCount: Int! policyPendingHighCount: Int! policyPendingCriticalCount: Int! - serviceVolumePerHour: Float - serviceCostPerHourVolumeUsd: Float - logEventVolumePerHour: Float - logEventBytesPerHour: Float - logEventCostPerHourBytesUsd: Float - logEventCostPerHourVolumeUsd: Float - logEventCostPerHourUsd: Float - estimatedVolumeReductionPerHour: Float - estimatedBytesReductionPerHour: Float - estimatedCostReductionPerHourBytesUsd: Float - estimatedCostReductionPerHourVolumeUsd: Float - estimatedCostReductionPerHourUsd: Float - observedVolumePerHourBefore: Float - observedVolumePerHourAfter: Float - observedBytesPerHourBefore: Float - observedBytesPerHourAfter: Float - observedCostPerHourBeforeBytesUsd: Float - observedCostPerHourBeforeVolumeUsd: Float - observedCostPerHourBeforeUsd: Float - observedCostPerHourAfterBytesUsd: Float - observedCostPerHourAfterVolumeUsd: Float - observedCostPerHourAfterUsd: Float + currentServiceEventsPerHour: Float + currentServiceVolumeUsdPerHour: Float + currentEventsPerHour: Float + currentBytesPerHour: Float + currentBytesUsdPerHour: Float + currentVolumeUsdPerHour: Float + currentTotalUsdPerHour: Float + estimatedEventsPerHour: Float + estimatedBytesPerHour: Float + estimatedBytesUsdPerHour: Float + estimatedVolumeUsdPerHour: Float + estimatedTotalUsdPerHour: Float + impactEventsPerHour: Float + impactBytesPerHour: Float + impactBytesUsdPerHour: Float + impactVolumeUsdPerHour: Float + impactTotalUsdPerHour: Float refreshedAt: Time! } @@ -1094,35 +1086,45 @@ input DatadogAccountStatusCacheWhereInput { logEventCountLT: Int logEventCountLTE: Int - """policy_pending_count field predicates""" - policyPendingCount: Int - policyPendingCountNEQ: Int - policyPendingCountIn: [Int!] - policyPendingCountNotIn: [Int!] - policyPendingCountGT: Int - policyPendingCountGTE: Int - policyPendingCountLT: Int - policyPendingCountLTE: Int - - """policy_approved_count field predicates""" - policyApprovedCount: Int - policyApprovedCountNEQ: Int - policyApprovedCountIn: [Int!] - policyApprovedCountNotIn: [Int!] - policyApprovedCountGT: Int - policyApprovedCountGTE: Int - policyApprovedCountLT: Int - policyApprovedCountLTE: Int - - """policy_dismissed_count field predicates""" - policyDismissedCount: Int - policyDismissedCountNEQ: Int - policyDismissedCountIn: [Int!] - policyDismissedCountNotIn: [Int!] - policyDismissedCountGT: Int - policyDismissedCountGTE: Int - policyDismissedCountLT: Int - policyDismissedCountLTE: Int + """recommendation_count field predicates""" + recommendationCount: Int + recommendationCountNEQ: Int + recommendationCountIn: [Int!] + recommendationCountNotIn: [Int!] + recommendationCountGT: Int + recommendationCountGTE: Int + recommendationCountLT: Int + recommendationCountLTE: Int + + """pending_recommendation_count field predicates""" + pendingRecommendationCount: Int + pendingRecommendationCountNEQ: Int + pendingRecommendationCountIn: [Int!] + pendingRecommendationCountNotIn: [Int!] + pendingRecommendationCountGT: Int + pendingRecommendationCountGTE: Int + pendingRecommendationCountLT: Int + pendingRecommendationCountLTE: Int + + """approved_recommendation_count field predicates""" + approvedRecommendationCount: Int + approvedRecommendationCountNEQ: Int + approvedRecommendationCountIn: [Int!] + approvedRecommendationCountNotIn: [Int!] + approvedRecommendationCountGT: Int + approvedRecommendationCountGTE: Int + approvedRecommendationCountLT: Int + approvedRecommendationCountLTE: Int + + """dismissed_recommendation_count field predicates""" + dismissedRecommendationCount: Int + dismissedRecommendationCountNEQ: Int + dismissedRecommendationCountIn: [Int!] + dismissedRecommendationCountNotIn: [Int!] + dismissedRecommendationCountGT: Int + dismissedRecommendationCountGTE: Int + dismissedRecommendationCountLT: Int + dismissedRecommendationCountLTE: Int """policy_pending_low_count field predicates""" policyPendingLowCount: Int @@ -1164,269 +1166,209 @@ input DatadogAccountStatusCacheWhereInput { policyPendingCriticalCountLT: Int policyPendingCriticalCountLTE: Int - """service_volume_per_hour field predicates""" - serviceVolumePerHour: Float - serviceVolumePerHourNEQ: Float - serviceVolumePerHourIn: [Float!] - serviceVolumePerHourNotIn: [Float!] - serviceVolumePerHourGT: Float - serviceVolumePerHourGTE: Float - serviceVolumePerHourLT: Float - serviceVolumePerHourLTE: Float - serviceVolumePerHourIsNil: Boolean - serviceVolumePerHourNotNil: Boolean - - """service_cost_per_hour_volume_usd field predicates""" - serviceCostPerHourVolumeUsd: Float - serviceCostPerHourVolumeUsdNEQ: Float - serviceCostPerHourVolumeUsdIn: [Float!] - serviceCostPerHourVolumeUsdNotIn: [Float!] - serviceCostPerHourVolumeUsdGT: Float - serviceCostPerHourVolumeUsdGTE: Float - serviceCostPerHourVolumeUsdLT: Float - serviceCostPerHourVolumeUsdLTE: Float - serviceCostPerHourVolumeUsdIsNil: Boolean - serviceCostPerHourVolumeUsdNotNil: Boolean - - """log_event_volume_per_hour field predicates""" - logEventVolumePerHour: Float - logEventVolumePerHourNEQ: Float - logEventVolumePerHourIn: [Float!] - logEventVolumePerHourNotIn: [Float!] - logEventVolumePerHourGT: Float - logEventVolumePerHourGTE: Float - logEventVolumePerHourLT: Float - logEventVolumePerHourLTE: Float - logEventVolumePerHourIsNil: Boolean - logEventVolumePerHourNotNil: Boolean - - """log_event_bytes_per_hour field predicates""" - logEventBytesPerHour: Float - logEventBytesPerHourNEQ: Float - logEventBytesPerHourIn: [Float!] - logEventBytesPerHourNotIn: [Float!] - logEventBytesPerHourGT: Float - logEventBytesPerHourGTE: Float - logEventBytesPerHourLT: Float - logEventBytesPerHourLTE: Float - logEventBytesPerHourIsNil: Boolean - logEventBytesPerHourNotNil: Boolean - - """log_event_cost_per_hour_bytes_usd field predicates""" - logEventCostPerHourBytesUsd: Float - logEventCostPerHourBytesUsdNEQ: Float - logEventCostPerHourBytesUsdIn: [Float!] - logEventCostPerHourBytesUsdNotIn: [Float!] - logEventCostPerHourBytesUsdGT: Float - logEventCostPerHourBytesUsdGTE: Float - logEventCostPerHourBytesUsdLT: Float - logEventCostPerHourBytesUsdLTE: Float - logEventCostPerHourBytesUsdIsNil: Boolean - logEventCostPerHourBytesUsdNotNil: Boolean - - """log_event_cost_per_hour_volume_usd field predicates""" - logEventCostPerHourVolumeUsd: Float - logEventCostPerHourVolumeUsdNEQ: Float - logEventCostPerHourVolumeUsdIn: [Float!] - logEventCostPerHourVolumeUsdNotIn: [Float!] - logEventCostPerHourVolumeUsdGT: Float - logEventCostPerHourVolumeUsdGTE: Float - logEventCostPerHourVolumeUsdLT: Float - logEventCostPerHourVolumeUsdLTE: Float - logEventCostPerHourVolumeUsdIsNil: Boolean - logEventCostPerHourVolumeUsdNotNil: Boolean - - """log_event_cost_per_hour_usd field predicates""" - logEventCostPerHourUsd: Float - logEventCostPerHourUsdNEQ: Float - logEventCostPerHourUsdIn: [Float!] - logEventCostPerHourUsdNotIn: [Float!] - logEventCostPerHourUsdGT: Float - logEventCostPerHourUsdGTE: Float - logEventCostPerHourUsdLT: Float - logEventCostPerHourUsdLTE: Float - logEventCostPerHourUsdIsNil: Boolean - logEventCostPerHourUsdNotNil: Boolean - - """estimated_volume_reduction_per_hour field predicates""" - estimatedVolumeReductionPerHour: Float - estimatedVolumeReductionPerHourNEQ: Float - estimatedVolumeReductionPerHourIn: [Float!] - estimatedVolumeReductionPerHourNotIn: [Float!] - estimatedVolumeReductionPerHourGT: Float - estimatedVolumeReductionPerHourGTE: Float - estimatedVolumeReductionPerHourLT: Float - estimatedVolumeReductionPerHourLTE: Float - estimatedVolumeReductionPerHourIsNil: Boolean - estimatedVolumeReductionPerHourNotNil: Boolean - - """estimated_bytes_reduction_per_hour field predicates""" - estimatedBytesReductionPerHour: Float - estimatedBytesReductionPerHourNEQ: Float - estimatedBytesReductionPerHourIn: [Float!] - estimatedBytesReductionPerHourNotIn: [Float!] - estimatedBytesReductionPerHourGT: Float - estimatedBytesReductionPerHourGTE: Float - estimatedBytesReductionPerHourLT: Float - estimatedBytesReductionPerHourLTE: Float - estimatedBytesReductionPerHourIsNil: Boolean - estimatedBytesReductionPerHourNotNil: Boolean - - """estimated_cost_reduction_per_hour_bytes_usd field predicates""" - estimatedCostReductionPerHourBytesUsd: Float - estimatedCostReductionPerHourBytesUsdNEQ: Float - estimatedCostReductionPerHourBytesUsdIn: [Float!] - estimatedCostReductionPerHourBytesUsdNotIn: [Float!] - estimatedCostReductionPerHourBytesUsdGT: Float - estimatedCostReductionPerHourBytesUsdGTE: Float - estimatedCostReductionPerHourBytesUsdLT: Float - estimatedCostReductionPerHourBytesUsdLTE: Float - estimatedCostReductionPerHourBytesUsdIsNil: Boolean - estimatedCostReductionPerHourBytesUsdNotNil: Boolean - - """estimated_cost_reduction_per_hour_volume_usd field predicates""" - estimatedCostReductionPerHourVolumeUsd: Float - estimatedCostReductionPerHourVolumeUsdNEQ: Float - estimatedCostReductionPerHourVolumeUsdIn: [Float!] - estimatedCostReductionPerHourVolumeUsdNotIn: [Float!] - estimatedCostReductionPerHourVolumeUsdGT: Float - estimatedCostReductionPerHourVolumeUsdGTE: Float - estimatedCostReductionPerHourVolumeUsdLT: Float - estimatedCostReductionPerHourVolumeUsdLTE: Float - estimatedCostReductionPerHourVolumeUsdIsNil: Boolean - estimatedCostReductionPerHourVolumeUsdNotNil: Boolean - - """estimated_cost_reduction_per_hour_usd field predicates""" - estimatedCostReductionPerHourUsd: Float - estimatedCostReductionPerHourUsdNEQ: Float - estimatedCostReductionPerHourUsdIn: [Float!] - estimatedCostReductionPerHourUsdNotIn: [Float!] - estimatedCostReductionPerHourUsdGT: Float - estimatedCostReductionPerHourUsdGTE: Float - estimatedCostReductionPerHourUsdLT: Float - estimatedCostReductionPerHourUsdLTE: Float - estimatedCostReductionPerHourUsdIsNil: Boolean - estimatedCostReductionPerHourUsdNotNil: Boolean - - """observed_volume_per_hour_before field predicates""" - observedVolumePerHourBefore: Float - observedVolumePerHourBeforeNEQ: Float - observedVolumePerHourBeforeIn: [Float!] - observedVolumePerHourBeforeNotIn: [Float!] - observedVolumePerHourBeforeGT: Float - observedVolumePerHourBeforeGTE: Float - observedVolumePerHourBeforeLT: Float - observedVolumePerHourBeforeLTE: Float - observedVolumePerHourBeforeIsNil: Boolean - observedVolumePerHourBeforeNotNil: Boolean - - """observed_volume_per_hour_after field predicates""" - observedVolumePerHourAfter: Float - observedVolumePerHourAfterNEQ: Float - observedVolumePerHourAfterIn: [Float!] - observedVolumePerHourAfterNotIn: [Float!] - observedVolumePerHourAfterGT: Float - observedVolumePerHourAfterGTE: Float - observedVolumePerHourAfterLT: Float - observedVolumePerHourAfterLTE: Float - observedVolumePerHourAfterIsNil: Boolean - observedVolumePerHourAfterNotNil: Boolean - - """observed_bytes_per_hour_before field predicates""" - observedBytesPerHourBefore: Float - observedBytesPerHourBeforeNEQ: Float - observedBytesPerHourBeforeIn: [Float!] - observedBytesPerHourBeforeNotIn: [Float!] - observedBytesPerHourBeforeGT: Float - observedBytesPerHourBeforeGTE: Float - observedBytesPerHourBeforeLT: Float - observedBytesPerHourBeforeLTE: Float - observedBytesPerHourBeforeIsNil: Boolean - observedBytesPerHourBeforeNotNil: Boolean - - """observed_bytes_per_hour_after field predicates""" - observedBytesPerHourAfter: Float - observedBytesPerHourAfterNEQ: Float - observedBytesPerHourAfterIn: [Float!] - observedBytesPerHourAfterNotIn: [Float!] - observedBytesPerHourAfterGT: Float - observedBytesPerHourAfterGTE: Float - observedBytesPerHourAfterLT: Float - observedBytesPerHourAfterLTE: Float - observedBytesPerHourAfterIsNil: Boolean - observedBytesPerHourAfterNotNil: Boolean - - """observed_cost_per_hour_before_bytes_usd field predicates""" - observedCostPerHourBeforeBytesUsd: Float - observedCostPerHourBeforeBytesUsdNEQ: Float - observedCostPerHourBeforeBytesUsdIn: [Float!] - observedCostPerHourBeforeBytesUsdNotIn: [Float!] - observedCostPerHourBeforeBytesUsdGT: Float - observedCostPerHourBeforeBytesUsdGTE: Float - observedCostPerHourBeforeBytesUsdLT: Float - observedCostPerHourBeforeBytesUsdLTE: Float - observedCostPerHourBeforeBytesUsdIsNil: Boolean - observedCostPerHourBeforeBytesUsdNotNil: Boolean - - """observed_cost_per_hour_before_volume_usd field predicates""" - observedCostPerHourBeforeVolumeUsd: Float - observedCostPerHourBeforeVolumeUsdNEQ: Float - observedCostPerHourBeforeVolumeUsdIn: [Float!] - observedCostPerHourBeforeVolumeUsdNotIn: [Float!] - observedCostPerHourBeforeVolumeUsdGT: Float - observedCostPerHourBeforeVolumeUsdGTE: Float - observedCostPerHourBeforeVolumeUsdLT: Float - observedCostPerHourBeforeVolumeUsdLTE: Float - observedCostPerHourBeforeVolumeUsdIsNil: Boolean - observedCostPerHourBeforeVolumeUsdNotNil: Boolean - - """observed_cost_per_hour_before_usd field predicates""" - observedCostPerHourBeforeUsd: Float - observedCostPerHourBeforeUsdNEQ: Float - observedCostPerHourBeforeUsdIn: [Float!] - observedCostPerHourBeforeUsdNotIn: [Float!] - observedCostPerHourBeforeUsdGT: Float - observedCostPerHourBeforeUsdGTE: Float - observedCostPerHourBeforeUsdLT: Float - observedCostPerHourBeforeUsdLTE: Float - observedCostPerHourBeforeUsdIsNil: Boolean - observedCostPerHourBeforeUsdNotNil: Boolean - - """observed_cost_per_hour_after_bytes_usd field predicates""" - observedCostPerHourAfterBytesUsd: Float - observedCostPerHourAfterBytesUsdNEQ: Float - observedCostPerHourAfterBytesUsdIn: [Float!] - observedCostPerHourAfterBytesUsdNotIn: [Float!] - observedCostPerHourAfterBytesUsdGT: Float - observedCostPerHourAfterBytesUsdGTE: Float - observedCostPerHourAfterBytesUsdLT: Float - observedCostPerHourAfterBytesUsdLTE: Float - observedCostPerHourAfterBytesUsdIsNil: Boolean - observedCostPerHourAfterBytesUsdNotNil: Boolean - - """observed_cost_per_hour_after_volume_usd field predicates""" - observedCostPerHourAfterVolumeUsd: Float - observedCostPerHourAfterVolumeUsdNEQ: Float - observedCostPerHourAfterVolumeUsdIn: [Float!] - observedCostPerHourAfterVolumeUsdNotIn: [Float!] - observedCostPerHourAfterVolumeUsdGT: Float - observedCostPerHourAfterVolumeUsdGTE: Float - observedCostPerHourAfterVolumeUsdLT: Float - observedCostPerHourAfterVolumeUsdLTE: Float - observedCostPerHourAfterVolumeUsdIsNil: Boolean - observedCostPerHourAfterVolumeUsdNotNil: Boolean - - """observed_cost_per_hour_after_usd field predicates""" - observedCostPerHourAfterUsd: Float - observedCostPerHourAfterUsdNEQ: Float - observedCostPerHourAfterUsdIn: [Float!] - observedCostPerHourAfterUsdNotIn: [Float!] - observedCostPerHourAfterUsdGT: Float - observedCostPerHourAfterUsdGTE: Float - observedCostPerHourAfterUsdLT: Float - observedCostPerHourAfterUsdLTE: Float - observedCostPerHourAfterUsdIsNil: Boolean - observedCostPerHourAfterUsdNotNil: Boolean + """current_service_events_per_hour field predicates""" + currentServiceEventsPerHour: Float + currentServiceEventsPerHourNEQ: Float + currentServiceEventsPerHourIn: [Float!] + currentServiceEventsPerHourNotIn: [Float!] + currentServiceEventsPerHourGT: Float + currentServiceEventsPerHourGTE: Float + currentServiceEventsPerHourLT: Float + currentServiceEventsPerHourLTE: Float + currentServiceEventsPerHourIsNil: Boolean + currentServiceEventsPerHourNotNil: Boolean + + """current_service_volume_usd_per_hour field predicates""" + currentServiceVolumeUsdPerHour: Float + currentServiceVolumeUsdPerHourNEQ: Float + currentServiceVolumeUsdPerHourIn: [Float!] + currentServiceVolumeUsdPerHourNotIn: [Float!] + currentServiceVolumeUsdPerHourGT: Float + currentServiceVolumeUsdPerHourGTE: Float + currentServiceVolumeUsdPerHourLT: Float + currentServiceVolumeUsdPerHourLTE: Float + currentServiceVolumeUsdPerHourIsNil: Boolean + currentServiceVolumeUsdPerHourNotNil: Boolean + + """current_events_per_hour field predicates""" + currentEventsPerHour: Float + currentEventsPerHourNEQ: Float + currentEventsPerHourIn: [Float!] + currentEventsPerHourNotIn: [Float!] + currentEventsPerHourGT: Float + currentEventsPerHourGTE: Float + currentEventsPerHourLT: Float + currentEventsPerHourLTE: Float + currentEventsPerHourIsNil: Boolean + currentEventsPerHourNotNil: Boolean + + """current_bytes_per_hour field predicates""" + currentBytesPerHour: Float + currentBytesPerHourNEQ: Float + currentBytesPerHourIn: [Float!] + currentBytesPerHourNotIn: [Float!] + currentBytesPerHourGT: Float + currentBytesPerHourGTE: Float + currentBytesPerHourLT: Float + currentBytesPerHourLTE: Float + currentBytesPerHourIsNil: Boolean + currentBytesPerHourNotNil: Boolean + + """current_bytes_usd_per_hour field predicates""" + currentBytesUsdPerHour: Float + currentBytesUsdPerHourNEQ: Float + currentBytesUsdPerHourIn: [Float!] + currentBytesUsdPerHourNotIn: [Float!] + currentBytesUsdPerHourGT: Float + currentBytesUsdPerHourGTE: Float + currentBytesUsdPerHourLT: Float + currentBytesUsdPerHourLTE: Float + currentBytesUsdPerHourIsNil: Boolean + currentBytesUsdPerHourNotNil: Boolean + + """current_volume_usd_per_hour field predicates""" + currentVolumeUsdPerHour: Float + currentVolumeUsdPerHourNEQ: Float + currentVolumeUsdPerHourIn: [Float!] + currentVolumeUsdPerHourNotIn: [Float!] + currentVolumeUsdPerHourGT: Float + currentVolumeUsdPerHourGTE: Float + currentVolumeUsdPerHourLT: Float + currentVolumeUsdPerHourLTE: Float + currentVolumeUsdPerHourIsNil: Boolean + currentVolumeUsdPerHourNotNil: Boolean + + """current_total_usd_per_hour field predicates""" + currentTotalUsdPerHour: Float + currentTotalUsdPerHourNEQ: Float + currentTotalUsdPerHourIn: [Float!] + currentTotalUsdPerHourNotIn: [Float!] + currentTotalUsdPerHourGT: Float + currentTotalUsdPerHourGTE: Float + currentTotalUsdPerHourLT: Float + currentTotalUsdPerHourLTE: Float + currentTotalUsdPerHourIsNil: Boolean + currentTotalUsdPerHourNotNil: Boolean + + """estimated_events_per_hour field predicates""" + estimatedEventsPerHour: Float + estimatedEventsPerHourNEQ: Float + estimatedEventsPerHourIn: [Float!] + estimatedEventsPerHourNotIn: [Float!] + estimatedEventsPerHourGT: Float + estimatedEventsPerHourGTE: Float + estimatedEventsPerHourLT: Float + estimatedEventsPerHourLTE: Float + estimatedEventsPerHourIsNil: Boolean + estimatedEventsPerHourNotNil: Boolean + + """estimated_bytes_per_hour field predicates""" + estimatedBytesPerHour: Float + estimatedBytesPerHourNEQ: Float + estimatedBytesPerHourIn: [Float!] + estimatedBytesPerHourNotIn: [Float!] + estimatedBytesPerHourGT: Float + estimatedBytesPerHourGTE: Float + estimatedBytesPerHourLT: Float + estimatedBytesPerHourLTE: Float + estimatedBytesPerHourIsNil: Boolean + estimatedBytesPerHourNotNil: Boolean + + """estimated_bytes_usd_per_hour field predicates""" + estimatedBytesUsdPerHour: Float + estimatedBytesUsdPerHourNEQ: Float + estimatedBytesUsdPerHourIn: [Float!] + estimatedBytesUsdPerHourNotIn: [Float!] + estimatedBytesUsdPerHourGT: Float + estimatedBytesUsdPerHourGTE: Float + estimatedBytesUsdPerHourLT: Float + estimatedBytesUsdPerHourLTE: Float + estimatedBytesUsdPerHourIsNil: Boolean + estimatedBytesUsdPerHourNotNil: Boolean + + """estimated_volume_usd_per_hour field predicates""" + estimatedVolumeUsdPerHour: Float + estimatedVolumeUsdPerHourNEQ: Float + estimatedVolumeUsdPerHourIn: [Float!] + estimatedVolumeUsdPerHourNotIn: [Float!] + estimatedVolumeUsdPerHourGT: Float + estimatedVolumeUsdPerHourGTE: Float + estimatedVolumeUsdPerHourLT: Float + estimatedVolumeUsdPerHourLTE: Float + estimatedVolumeUsdPerHourIsNil: Boolean + estimatedVolumeUsdPerHourNotNil: Boolean + + """estimated_total_usd_per_hour field predicates""" + estimatedTotalUsdPerHour: Float + estimatedTotalUsdPerHourNEQ: Float + estimatedTotalUsdPerHourIn: [Float!] + estimatedTotalUsdPerHourNotIn: [Float!] + estimatedTotalUsdPerHourGT: Float + estimatedTotalUsdPerHourGTE: Float + estimatedTotalUsdPerHourLT: Float + estimatedTotalUsdPerHourLTE: Float + estimatedTotalUsdPerHourIsNil: Boolean + estimatedTotalUsdPerHourNotNil: Boolean + + """impact_events_per_hour field predicates""" + impactEventsPerHour: Float + impactEventsPerHourNEQ: Float + impactEventsPerHourIn: [Float!] + impactEventsPerHourNotIn: [Float!] + impactEventsPerHourGT: Float + impactEventsPerHourGTE: Float + impactEventsPerHourLT: Float + impactEventsPerHourLTE: Float + impactEventsPerHourIsNil: Boolean + impactEventsPerHourNotNil: Boolean + + """impact_bytes_per_hour field predicates""" + impactBytesPerHour: Float + impactBytesPerHourNEQ: Float + impactBytesPerHourIn: [Float!] + impactBytesPerHourNotIn: [Float!] + impactBytesPerHourGT: Float + impactBytesPerHourGTE: Float + impactBytesPerHourLT: Float + impactBytesPerHourLTE: Float + impactBytesPerHourIsNil: Boolean + impactBytesPerHourNotNil: Boolean + + """impact_bytes_usd_per_hour field predicates""" + impactBytesUsdPerHour: Float + impactBytesUsdPerHourNEQ: Float + impactBytesUsdPerHourIn: [Float!] + impactBytesUsdPerHourNotIn: [Float!] + impactBytesUsdPerHourGT: Float + impactBytesUsdPerHourGTE: Float + impactBytesUsdPerHourLT: Float + impactBytesUsdPerHourLTE: Float + impactBytesUsdPerHourIsNil: Boolean + impactBytesUsdPerHourNotNil: Boolean + + """impact_volume_usd_per_hour field predicates""" + impactVolumeUsdPerHour: Float + impactVolumeUsdPerHourNEQ: Float + impactVolumeUsdPerHourIn: [Float!] + impactVolumeUsdPerHourNotIn: [Float!] + impactVolumeUsdPerHourGT: Float + impactVolumeUsdPerHourGTE: Float + impactVolumeUsdPerHourLT: Float + impactVolumeUsdPerHourLTE: Float + impactVolumeUsdPerHourIsNil: Boolean + impactVolumeUsdPerHourNotNil: Boolean + + """impact_total_usd_per_hour field predicates""" + impactTotalUsdPerHour: Float + impactTotalUsdPerHourNEQ: Float + impactTotalUsdPerHourIn: [Float!] + impactTotalUsdPerHourNotIn: [Float!] + impactTotalUsdPerHourGT: Float + impactTotalUsdPerHourGTE: Float + impactTotalUsdPerHourLT: Float + impactTotalUsdPerHourLTE: Float + impactTotalUsdPerHourIsNil: Boolean + impactTotalUsdPerHourNotNil: Boolean """refreshed_at field predicates""" refreshedAt: Time @@ -1674,6 +1616,10 @@ input DatadogLogIndexWhereInput { hasDatadogAccountWith: [DatadogAccountWhereInput!] } +input DatadogTargetInput { + accountIds: [ID!] +} + type EdgeApiKey implements Node { """Unique identifier of this API key""" id: ID! @@ -2043,6 +1989,174 @@ input EdgeInstanceWhereInput { hasAccountWith: [AccountWhereInput!] } +input EdgeTargetInput { + resourceSelectors: [ResourceSelectorInput!] +} + +input EnforcementTargetInput { + edge: EdgeTargetInput + datadog: DatadogTargetInput +} + +type Finding implements Node { + """Unique identifier""" + id: ID! + + """Parent account this finding belongs to""" + accountID: ID! + + """Finding kind identifier, e.g. noisy_404s.""" + kind: String! + + """ + Specific detector profile within the finding kind, e.g. misconfigured_integration. + """ + profile: String! + + """ + Version of the detector logic that most recently reconciled this finding. + """ + detectorVersion: Int! + + """ + Stable detector-specific identity for this finding instance within an account. + """ + fingerprint: String! + + """When this finding row was created.""" + createdAt: Time! + + """When this finding row was last updated.""" + updatedAt: Time! + + """Account this finding belongs to""" + account: Account! +} + +"""Ordering options for Finding connections""" +input FindingOrder { + """The ordering direction.""" + direction: OrderDirection! = ASC + + """The field by which to order Findings.""" + field: FindingOrderField! +} + +"""Properties by which Finding connections can be ordered.""" +enum FindingOrderField { + KIND + PROFILE + DETECTOR_VERSION + FINGERPRINT + CREATED_AT + UPDATED_AT +} + +""" +FindingWhereInput is used for filtering Finding objects. +Input was generated by ent. +""" +input FindingWhereInput { + not: FindingWhereInput + and: [FindingWhereInput!] + or: [FindingWhereInput!] + + """id field predicates""" + id: ID + idNEQ: ID + idIn: [ID!] + idNotIn: [ID!] + idGT: ID + idGTE: ID + idLT: ID + idLTE: ID + + """account_id field predicates""" + accountID: ID + accountIDNEQ: ID + accountIDIn: [ID!] + accountIDNotIn: [ID!] + + """kind field predicates""" + kind: String + kindNEQ: String + kindIn: [String!] + kindNotIn: [String!] + kindGT: String + kindGTE: String + kindLT: String + kindLTE: String + kindContains: String + kindHasPrefix: String + kindHasSuffix: String + kindEqualFold: String + kindContainsFold: String + + """profile field predicates""" + profile: String + profileNEQ: String + profileIn: [String!] + profileNotIn: [String!] + profileGT: String + profileGTE: String + profileLT: String + profileLTE: String + profileContains: String + profileHasPrefix: String + profileHasSuffix: String + profileEqualFold: String + profileContainsFold: String + + """detector_version field predicates""" + detectorVersion: Int + detectorVersionNEQ: Int + detectorVersionIn: [Int!] + detectorVersionNotIn: [Int!] + detectorVersionGT: Int + detectorVersionGTE: Int + detectorVersionLT: Int + detectorVersionLTE: Int + + """fingerprint field predicates""" + fingerprint: String + fingerprintNEQ: String + fingerprintIn: [String!] + fingerprintNotIn: [String!] + fingerprintGT: String + fingerprintGTE: String + fingerprintLT: String + fingerprintLTE: String + fingerprintContains: String + fingerprintHasPrefix: String + fingerprintHasSuffix: String + fingerprintEqualFold: String + fingerprintContainsFold: String + + """created_at field predicates""" + createdAt: Time + createdAtNEQ: Time + createdAtIn: [Time!] + createdAtNotIn: [Time!] + createdAtGT: Time + createdAtGTE: Time + createdAtLT: Time + createdAtLTE: Time + + """updated_at field predicates""" + updatedAt: Time + updatedAtNEQ: Time + updatedAtIn: [Time!] + updatedAtNotIn: [Time!] + updatedAtGT: Time + updatedAtGTE: Time + updatedAtLT: Time + updatedAtLTE: Time + + """account edge predicates""" + hasAccount: Boolean + hasAccountWith: [AccountWhereInput!] +} + type LogEvent implements Node { """Unique identifier of the log event""" id: ID! @@ -2070,24 +2184,12 @@ type LogEvent implements Node { severity: LogEventSeverity """ - What role this event serves: diagnostic (investigate incidents), operational - (system behavior), lifecycle (state transitions), ephemeral (transient state). - """ - signalPurpose: LogEventSignalPurpose! - - """ - What this event records: system (internal mechanics), traffic (request flow), - activity (actor+action+resource), control (access/permission decisions). - """ - eventNature: LogEventEventNature! - - """ - True when this event represents a multi-line fragment rather than a complete log entry. Set by the classifier. + True when this event represents a multi-line fragment rather than a complete log entry. Set during fingerprinting. """ isFragment: Boolean! """ - Sample log records captured during discovery, used for AI analysis and pattern validation + Sample log records captured during catalog loop collection, used for AI inference and pattern validation. """ examples: [LogRecord!]! @@ -2110,15 +2212,18 @@ type LogEvent implements Node { """Service that produces this event""" service: Service! - """Log sample that produced this event during classification""" + """Log sample that produced this event during fingerprinting.""" logSample: LogSample! """Category-specific policies across workspaces""" - policies: [LogEventPolicy!] + policies: [LogEventRecommendation!] """Fields discovered in this event's example records""" logEventFields: [LogEventField!] + """Extensible typed facts attached to this log event""" + facts: [LogEventFact!] + """ Status of this log event. Shows where the log event is in the preparation pipeline. @@ -2148,12 +2253,139 @@ type LogEventEdge { cursor: Cursor! } -"""LogEventEventNature is enum for the field event_nature""" -enum LogEventEventNature { - system - traffic - activity - control +type LogEventFact implements Node { + """Unique identifier""" + id: ID! + + """ + Denormalized for tenant isolation. Auto-set via trigger from log_event.account_id. + """ + accountID: UUID! + + """The log event this fact belongs to""" + logEventID: ID! + + """Fact namespace, e.g. catalog, quality, security.""" + namespace: String! + + """Fact type within the namespace, e.g. signal_purpose, body_kind.""" + factType: String! + + """When this fact was first recorded""" + createdAt: Time! + + """When this fact was last refreshed""" + updatedAt: Time! + + """The log event this fact belongs to""" + logEvent: LogEvent! +} + +"""Ordering options for LogEventFact connections""" +input LogEventFactOrder { + """The ordering direction.""" + direction: OrderDirection! = ASC + + """The field by which to order LogEventFacts.""" + field: LogEventFactOrderField! +} + +"""Properties by which LogEventFact connections can be ordered.""" +enum LogEventFactOrderField { + NAMESPACE + FACT_TYPE + CREATED_AT + UPDATED_AT +} + +""" +LogEventFactWhereInput is used for filtering LogEventFact objects. +Input was generated by ent. +""" +input LogEventFactWhereInput { + not: LogEventFactWhereInput + and: [LogEventFactWhereInput!] + or: [LogEventFactWhereInput!] + + """id field predicates""" + id: ID + idNEQ: ID + idIn: [ID!] + idNotIn: [ID!] + idGT: ID + idGTE: ID + idLT: ID + idLTE: ID + + """account_id field predicates""" + accountID: UUID + accountIDNEQ: UUID + accountIDIn: [UUID!] + accountIDNotIn: [UUID!] + accountIDGT: UUID + accountIDGTE: UUID + accountIDLT: UUID + accountIDLTE: UUID + + """log_event_id field predicates""" + logEventID: ID + logEventIDNEQ: ID + logEventIDIn: [ID!] + logEventIDNotIn: [ID!] + + """namespace field predicates""" + namespace: String + namespaceNEQ: String + namespaceIn: [String!] + namespaceNotIn: [String!] + namespaceGT: String + namespaceGTE: String + namespaceLT: String + namespaceLTE: String + namespaceContains: String + namespaceHasPrefix: String + namespaceHasSuffix: String + namespaceEqualFold: String + namespaceContainsFold: String + + """fact_type field predicates""" + factType: String + factTypeNEQ: String + factTypeIn: [String!] + factTypeNotIn: [String!] + factTypeGT: String + factTypeGTE: String + factTypeLT: String + factTypeLTE: String + factTypeContains: String + factTypeHasPrefix: String + factTypeHasSuffix: String + factTypeEqualFold: String + factTypeContainsFold: String + + """created_at field predicates""" + createdAt: Time + createdAtNEQ: Time + createdAtIn: [Time!] + createdAtNotIn: [Time!] + createdAtGT: Time + createdAtGTE: Time + createdAtLT: Time + createdAtLTE: Time + + """updated_at field predicates""" + updatedAt: Time + updatedAtNEQ: Time + updatedAtIn: [Time!] + updatedAtNotIn: [Time!] + updatedAtGT: Time + updatedAtGTE: Time + updatedAtLT: Time + updatedAtLTE: Time + + """log_event edge predicates""" + hasLogEvent: Boolean + hasLogEventWith: [LogEventWhereInput!] } type LogEventField implements Node { @@ -2184,6 +2416,144 @@ type LogEventField implements Node { """The log event this field belongs to""" logEvent: LogEvent! + + """Typed facts attached to this log event field""" + facts: [LogEventFieldFact!] +} + +type LogEventFieldFact implements Node { + """Unique identifier""" + id: ID! + + """ + Denormalized for tenant isolation. Auto-set via trigger from log_event_field.account_id. + """ + accountID: UUID! + + """The log event field this fact belongs to""" + logEventFieldID: ID! + + """Fact namespace, e.g. structure or semantic.""" + namespace: String! + + """Fact type within the namespace, e.g. value_profile or field_role.""" + factType: String! + + """When this fact was first recorded""" + createdAt: Time! + + """When this fact was last refreshed""" + updatedAt: Time! + + """The log event field this fact belongs to""" + logEventField: LogEventField! +} + +"""Ordering options for LogEventFieldFact connections""" +input LogEventFieldFactOrder { + """The ordering direction.""" + direction: OrderDirection! = ASC + + """The field by which to order LogEventFieldFacts.""" + field: LogEventFieldFactOrderField! +} + +"""Properties by which LogEventFieldFact connections can be ordered.""" +enum LogEventFieldFactOrderField { + NAMESPACE + FACT_TYPE + CREATED_AT + UPDATED_AT +} + +""" +LogEventFieldFactWhereInput is used for filtering LogEventFieldFact objects. +Input was generated by ent. +""" +input LogEventFieldFactWhereInput { + not: LogEventFieldFactWhereInput + and: [LogEventFieldFactWhereInput!] + or: [LogEventFieldFactWhereInput!] + + """id field predicates""" + id: ID + idNEQ: ID + idIn: [ID!] + idNotIn: [ID!] + idGT: ID + idGTE: ID + idLT: ID + idLTE: ID + + """account_id field predicates""" + accountID: UUID + accountIDNEQ: UUID + accountIDIn: [UUID!] + accountIDNotIn: [UUID!] + accountIDGT: UUID + accountIDGTE: UUID + accountIDLT: UUID + accountIDLTE: UUID + + """log_event_field_id field predicates""" + logEventFieldID: ID + logEventFieldIDNEQ: ID + logEventFieldIDIn: [ID!] + logEventFieldIDNotIn: [ID!] + + """namespace field predicates""" + namespace: String + namespaceNEQ: String + namespaceIn: [String!] + namespaceNotIn: [String!] + namespaceGT: String + namespaceGTE: String + namespaceLT: String + namespaceLTE: String + namespaceContains: String + namespaceHasPrefix: String + namespaceHasSuffix: String + namespaceEqualFold: String + namespaceContainsFold: String + + """fact_type field predicates""" + factType: String + factTypeNEQ: String + factTypeIn: [String!] + factTypeNotIn: [String!] + factTypeGT: String + factTypeGTE: String + factTypeLT: String + factTypeLTE: String + factTypeContains: String + factTypeHasPrefix: String + factTypeHasSuffix: String + factTypeEqualFold: String + factTypeContainsFold: String + + """created_at field predicates""" + createdAt: Time + createdAtNEQ: Time + createdAtIn: [Time!] + createdAtNotIn: [Time!] + createdAtGT: Time + createdAtGTE: Time + createdAtLT: Time + createdAtLTE: Time + + """updated_at field predicates""" + updatedAt: Time + updatedAtNEQ: Time + updatedAtIn: [Time!] + updatedAtNotIn: [Time!] + updatedAtGT: Time + updatedAtGTE: Time + updatedAtLT: Time + updatedAtLTE: Time + + """log_event_field edge predicates""" + hasLogEventField: Boolean + hasLogEventFieldWith: [LogEventFieldWhereInput!] } """ @@ -2266,6 +2636,10 @@ input LogEventFieldWhereInput { """log_event edge predicates""" hasLogEvent: Boolean hasLogEventWith: [LogEventWhereInput!] + + """facts edge predicates""" + hasFacts: Boolean + hasFactsWith: [LogEventFieldFactWhereInput!] } """Ordering options for LogEvent connections""" @@ -2281,13 +2655,11 @@ input LogEventOrder { enum LogEventOrderField { NAME SEVERITY - SIGNAL_PURPOSE - EVENT_NATURE CREATED_AT UPDATED_AT } -type LogEventPolicy implements Node { +type LogEventRecommendation implements Node { """Unique identifier""" id: ID! @@ -2309,7 +2681,7 @@ type LogEventPolicy implements Node { redundant_events, dead_weight. Quality: duplicate_fields, instrumentation_bloat, oversized_fields, wrong_level. """ - category: LogEventPolicyCategory! + category: LogEventRecommendationCategory! """ Whether this category requires AI judgment (true) vs mechanically verifiable @@ -2321,19 +2693,19 @@ type LogEventPolicy implements Node { Type of problem: compliance (legal/security risk), waste (event-level cuts), or quality (field-level improvements). Auto-set via trigger from CategoryMeta. """ - categoryType: LogEventPolicyCategoryType! + categoryType: LogEventRecommendationCategoryType! """ Max compliance severity across sensitivity types. NULL for non-compliance categories. Auto-set via trigger. """ - severity: LogEventPolicySeverity + severity: LogEventRecommendationSeverity """ What this policy does when enforced: 'drop' (remove all events), 'sample' (keep at reduced rate), 'filter' (drop subset by field value), 'trim' (remove/truncate fields), 'none' (informational only). Auto-set via trigger. """ - action: LogEventPolicyAction! + action: LogEventRecommendationAction! """When this policy was approved by a user""" approvedAt: Time @@ -2366,12 +2738,12 @@ type LogEventPolicy implements Node { """The log event this policy applies to""" logEvent: LogEvent! - """The workspace that owns this policy""" + """The workspace that owns this recommendation""" workspace: Workspace! } -"""LogEventPolicyAction is enum for the field action""" -enum LogEventPolicyAction { +"""LogEventRecommendationAction is enum for the field action""" +enum LogEventRecommendationAction { drop sample filter @@ -2379,8 +2751,8 @@ enum LogEventPolicyAction { none } -"""LogEventPolicyCategory is enum for the field category""" -enum LogEventPolicyCategory { +"""LogEventRecommendationCategory is enum for the field category""" +enum LogEventRecommendationCategory { pii_leakage secrets_leakage phi_leakage @@ -2399,7 +2771,7 @@ enum LogEventPolicyCategory { wrong_level } -type LogEventPolicyCategoryStatusCache implements Node { +type LogEventRecommendationCategoryStatusCache implements Node { id: ID! """Account ID for tenant isolation""" @@ -2411,7 +2783,7 @@ type LogEventPolicyCategoryStatusCache implements Node { """ Type of problem: compliance (legal/security risk), waste (event-level cuts), quality (field-level improvements). """ - categoryType: LogEventPolicyCategoryStatusCacheCategoryType! + categoryType: LogEventRecommendationCategoryStatusCacheCategoryType! """Human-readable category name (e.g., 'PII Leakage')""" displayName: String! @@ -2486,22 +2858,22 @@ type LogEventPolicyCategoryStatusCache implements Node { } """ -LogEventPolicyCategoryStatusCacheCategoryType is enum for the field category_type +LogEventRecommendationCategoryStatusCacheCategoryType is enum for the field category_type """ -enum LogEventPolicyCategoryStatusCacheCategoryType { +enum LogEventRecommendationCategoryStatusCacheCategoryType { compliance waste quality } """ -LogEventPolicyCategoryStatusCacheWhereInput is used for filtering LogEventPolicyCategoryStatusCache objects. +LogEventRecommendationCategoryStatusCacheWhereInput is used for filtering LogEventRecommendationCategoryStatusCache objects. Input was generated by ent. """ -input LogEventPolicyCategoryStatusCacheWhereInput { - not: LogEventPolicyCategoryStatusCacheWhereInput - and: [LogEventPolicyCategoryStatusCacheWhereInput!] - or: [LogEventPolicyCategoryStatusCacheWhereInput!] +input LogEventRecommendationCategoryStatusCacheWhereInput { + not: LogEventRecommendationCategoryStatusCacheWhereInput + and: [LogEventRecommendationCategoryStatusCacheWhereInput!] + or: [LogEventRecommendationCategoryStatusCacheWhereInput!] """id field predicates""" id: ID @@ -2539,10 +2911,10 @@ input LogEventPolicyCategoryStatusCacheWhereInput { categoryContainsFold: String """category_type field predicates""" - categoryType: LogEventPolicyCategoryStatusCacheCategoryType - categoryTypeNEQ: LogEventPolicyCategoryStatusCacheCategoryType - categoryTypeIn: [LogEventPolicyCategoryStatusCacheCategoryType!] - categoryTypeNotIn: [LogEventPolicyCategoryStatusCacheCategoryType!] + categoryType: LogEventRecommendationCategoryStatusCacheCategoryType + categoryTypeNEQ: LogEventRecommendationCategoryStatusCacheCategoryType + categoryTypeIn: [LogEventRecommendationCategoryStatusCacheCategoryType!] + categoryTypeNotIn: [LogEventRecommendationCategoryStatusCacheCategoryType!] """display_name field predicates""" displayName: String @@ -2771,17 +3143,17 @@ input LogEventPolicyCategoryStatusCacheWhereInput { refreshedAtLTE: Time } -"""LogEventPolicyCategoryType is enum for the field category_type""" -enum LogEventPolicyCategoryType { +"""LogEventRecommendationCategoryType is enum for the field category_type""" +enum LogEventRecommendationCategoryType { compliance waste quality } """A connection to a list of items.""" -type LogEventPolicyConnection { +type LogEventRecommendationConnection { """A list of edges.""" - edges: [LogEventPolicyEdge] + edges: [LogEventRecommendationEdge] """Information to aid in pagination.""" pageInfo: PageInfo! @@ -2791,25 +3163,25 @@ type LogEventPolicyConnection { } """An edge in a connection.""" -type LogEventPolicyEdge { +type LogEventRecommendationEdge { """The item at the end of the edge.""" - node: LogEventPolicy + node: LogEventRecommendation """A cursor for use in pagination.""" cursor: Cursor! } -"""Ordering options for LogEventPolicy connections""" -input LogEventPolicyOrder { +"""Ordering options for LogEventRecommendation connections""" +input LogEventRecommendationOrder { """The ordering direction.""" direction: OrderDirection! = ASC - """The field by which to order LogEventPolicies.""" - field: LogEventPolicyOrderField! + """The field by which to order LogEventRecommendations.""" + field: LogEventRecommendationOrderField! } -"""Properties by which LogEventPolicy connections can be ordered.""" -enum LogEventPolicyOrderField { +"""Properties by which LogEventRecommendation connections can be ordered.""" +enum LogEventRecommendationOrderField { CATEGORY SUBJECTIVE CATEGORY_TYPE @@ -2821,22 +3193,22 @@ enum LogEventPolicyOrderField { UPDATED_AT } -"""LogEventPolicySeverity is enum for the field severity""" -enum LogEventPolicySeverity { +"""LogEventRecommendationSeverity is enum for the field severity""" +enum LogEventRecommendationSeverity { low medium high critical } -type LogEventPolicyStatusCache implements Node { +type LogEventRecommendationStatusCache implements Node { id: ID! """Account ID for tenant isolation""" accountID: UUID! - """The policy this status row represents""" - policyID: ID! + """The recommendation this status row represents""" + recommendationID: ID! """The log event this policy targets""" logEventID: UUID! @@ -2853,7 +3225,7 @@ type LogEventPolicyStatusCache implements Node { User decision on this policy. PENDING (awaiting review), APPROVED (accepted for enforcement), DISMISSED (rejected by user). """ - status: LogEventPolicyStatusCacheStatus! + status: LogEventRecommendationStatusCacheStatus! """ Whether this category requires AI judgment (true) vs mechanically verifiable (false) @@ -2863,12 +3235,12 @@ type LogEventPolicyStatusCache implements Node { """ Type of problem: compliance (legal/security risk), waste (event-level cuts), quality (field-level improvements). """ - categoryType: LogEventPolicyStatusCacheCategoryType! + categoryType: LogEventRecommendationStatusCacheCategoryType! """ Max compliance severity across sensitivity types. NULL for non-compliance categories. """ - severity: LogEventPolicyStatusCacheSeverity + severity: LogEventRecommendationStatusCacheSeverity """When this policy was approved by a user""" approvedAt: Time @@ -2890,20 +3262,50 @@ type LogEventPolicyStatusCache implements Node { """ survivalRate: Float - """Events/hour saved if this policy applied alone. NULL if not estimable.""" - estimatedVolumeReductionPerHour: Float + """Current events/hour baseline for this recommendation""" + currentEventsPerHour: Float - """Bytes/hour saved if this policy applied alone. NULL if not estimable.""" - estimatedBytesReductionPerHour: Float + """Current bytes/hour baseline for this recommendation""" + currentBytesPerHour: Float - """Estimated ingestion savings in USD/hour from bytes reduction""" - estimatedCostReductionPerHourBytesUsd: Float + """Current bytes-billed USD/hour baseline""" + currentBytesUsdPerHour: Float - """Estimated indexing savings in USD/hour from volume reduction""" - estimatedCostReductionPerHourVolumeUsd: Float + """Current volume-billed USD/hour baseline""" + currentVolumeUsdPerHour: Float - """Estimated total savings in USD/hour (bytes + volume)""" - estimatedCostReductionPerHourUsd: Float + """Current total USD/hour baseline""" + currentTotalUsdPerHour: Float + + """Estimated events/hour if this recommendation is applied alone""" + estimatedEventsPerHour: Float + + """Estimated bytes/hour if this recommendation is applied alone""" + estimatedBytesPerHour: Float + + """Estimated bytes-billed USD/hour if applied alone""" + estimatedBytesUsdPerHour: Float + + """Estimated volume-billed USD/hour if applied alone""" + estimatedVolumeUsdPerHour: Float + + """Estimated total USD/hour if applied alone""" + estimatedTotalUsdPerHour: Float + + """Estimated impact in events/hour (estimated - current)""" + impactEventsPerHour: Float + + """Estimated impact in bytes/hour (estimated - current)""" + impactBytesPerHour: Float + + """Estimated impact in bytes-billed USD/hour (estimated - current)""" + impactBytesUsdPerHour: Float + + """Estimated impact in volume-billed USD/hour (estimated - current)""" + impactVolumeUsdPerHour: Float + + """Estimated impact in total USD/hour (estimated - current)""" + impactTotalUsdPerHour: Float """Service that produces the targeted log event (denormalized)""" serviceID: UUID @@ -2913,47 +3315,43 @@ type LogEventPolicyStatusCache implements Node { """Name of the targeted log event (denormalized for display)""" logEventName: String - - """Current throughput of the targeted log event in events/hour""" - volumePerHour: Float - - """Current throughput of the targeted log event in bytes/hour""" - bytesPerHour: Float refreshedAt: Time! } """ -LogEventPolicyStatusCacheCategoryType is enum for the field category_type +LogEventRecommendationStatusCacheCategoryType is enum for the field category_type """ -enum LogEventPolicyStatusCacheCategoryType { +enum LogEventRecommendationStatusCacheCategoryType { compliance waste quality } -"""LogEventPolicyStatusCacheSeverity is enum for the field severity""" -enum LogEventPolicyStatusCacheSeverity { +""" +LogEventRecommendationStatusCacheSeverity is enum for the field severity +""" +enum LogEventRecommendationStatusCacheSeverity { low medium high critical } -"""LogEventPolicyStatusCacheStatus is enum for the field status""" -enum LogEventPolicyStatusCacheStatus { +"""LogEventRecommendationStatusCacheStatus is enum for the field status""" +enum LogEventRecommendationStatusCacheStatus { PENDING APPROVED DISMISSED } """ -LogEventPolicyStatusCacheWhereInput is used for filtering LogEventPolicyStatusCache objects. +LogEventRecommendationStatusCacheWhereInput is used for filtering LogEventRecommendationStatusCache objects. Input was generated by ent. """ -input LogEventPolicyStatusCacheWhereInput { - not: LogEventPolicyStatusCacheWhereInput - and: [LogEventPolicyStatusCacheWhereInput!] - or: [LogEventPolicyStatusCacheWhereInput!] +input LogEventRecommendationStatusCacheWhereInput { + not: LogEventRecommendationStatusCacheWhereInput + and: [LogEventRecommendationStatusCacheWhereInput!] + or: [LogEventRecommendationStatusCacheWhereInput!] """id field predicates""" id: ID @@ -2975,11 +3373,11 @@ input LogEventPolicyStatusCacheWhereInput { accountIDLT: UUID accountIDLTE: UUID - """policy_id field predicates""" - policyID: ID - policyIDNEQ: ID - policyIDIn: [ID!] - policyIDNotIn: [ID!] + """recommendation_id field predicates""" + recommendationID: ID + recommendationIDNEQ: ID + recommendationIDIn: [ID!] + recommendationIDNotIn: [ID!] """log_event_id field predicates""" logEventID: UUID @@ -3017,26 +3415,26 @@ input LogEventPolicyStatusCacheWhereInput { categoryContainsFold: String """status field predicates""" - status: LogEventPolicyStatusCacheStatus - statusNEQ: LogEventPolicyStatusCacheStatus - statusIn: [LogEventPolicyStatusCacheStatus!] - statusNotIn: [LogEventPolicyStatusCacheStatus!] + status: LogEventRecommendationStatusCacheStatus + statusNEQ: LogEventRecommendationStatusCacheStatus + statusIn: [LogEventRecommendationStatusCacheStatus!] + statusNotIn: [LogEventRecommendationStatusCacheStatus!] """subjective field predicates""" subjective: Boolean subjectiveNEQ: Boolean """category_type field predicates""" - categoryType: LogEventPolicyStatusCacheCategoryType - categoryTypeNEQ: LogEventPolicyStatusCacheCategoryType - categoryTypeIn: [LogEventPolicyStatusCacheCategoryType!] - categoryTypeNotIn: [LogEventPolicyStatusCacheCategoryType!] + categoryType: LogEventRecommendationStatusCacheCategoryType + categoryTypeNEQ: LogEventRecommendationStatusCacheCategoryType + categoryTypeIn: [LogEventRecommendationStatusCacheCategoryType!] + categoryTypeNotIn: [LogEventRecommendationStatusCacheCategoryType!] """severity field predicates""" - severity: LogEventPolicyStatusCacheSeverity - severityNEQ: LogEventPolicyStatusCacheSeverity - severityIn: [LogEventPolicyStatusCacheSeverity!] - severityNotIn: [LogEventPolicyStatusCacheSeverity!] + severity: LogEventRecommendationStatusCacheSeverity + severityNEQ: LogEventRecommendationStatusCacheSeverity + severityIn: [LogEventRecommendationStatusCacheSeverity!] + severityNotIn: [LogEventRecommendationStatusCacheSeverity!] severityIsNil: Boolean severityNotNil: Boolean @@ -3103,65 +3501,185 @@ input LogEventPolicyStatusCacheWhereInput { survivalRateIsNil: Boolean survivalRateNotNil: Boolean - """estimated_volume_reduction_per_hour field predicates""" - estimatedVolumeReductionPerHour: Float - estimatedVolumeReductionPerHourNEQ: Float - estimatedVolumeReductionPerHourIn: [Float!] - estimatedVolumeReductionPerHourNotIn: [Float!] - estimatedVolumeReductionPerHourGT: Float - estimatedVolumeReductionPerHourGTE: Float - estimatedVolumeReductionPerHourLT: Float - estimatedVolumeReductionPerHourLTE: Float - estimatedVolumeReductionPerHourIsNil: Boolean - estimatedVolumeReductionPerHourNotNil: Boolean - - """estimated_bytes_reduction_per_hour field predicates""" - estimatedBytesReductionPerHour: Float - estimatedBytesReductionPerHourNEQ: Float - estimatedBytesReductionPerHourIn: [Float!] - estimatedBytesReductionPerHourNotIn: [Float!] - estimatedBytesReductionPerHourGT: Float - estimatedBytesReductionPerHourGTE: Float - estimatedBytesReductionPerHourLT: Float - estimatedBytesReductionPerHourLTE: Float - estimatedBytesReductionPerHourIsNil: Boolean - estimatedBytesReductionPerHourNotNil: Boolean - - """estimated_cost_reduction_per_hour_bytes_usd field predicates""" - estimatedCostReductionPerHourBytesUsd: Float - estimatedCostReductionPerHourBytesUsdNEQ: Float - estimatedCostReductionPerHourBytesUsdIn: [Float!] - estimatedCostReductionPerHourBytesUsdNotIn: [Float!] - estimatedCostReductionPerHourBytesUsdGT: Float - estimatedCostReductionPerHourBytesUsdGTE: Float - estimatedCostReductionPerHourBytesUsdLT: Float - estimatedCostReductionPerHourBytesUsdLTE: Float - estimatedCostReductionPerHourBytesUsdIsNil: Boolean - estimatedCostReductionPerHourBytesUsdNotNil: Boolean - - """estimated_cost_reduction_per_hour_volume_usd field predicates""" - estimatedCostReductionPerHourVolumeUsd: Float - estimatedCostReductionPerHourVolumeUsdNEQ: Float - estimatedCostReductionPerHourVolumeUsdIn: [Float!] - estimatedCostReductionPerHourVolumeUsdNotIn: [Float!] - estimatedCostReductionPerHourVolumeUsdGT: Float - estimatedCostReductionPerHourVolumeUsdGTE: Float - estimatedCostReductionPerHourVolumeUsdLT: Float - estimatedCostReductionPerHourVolumeUsdLTE: Float - estimatedCostReductionPerHourVolumeUsdIsNil: Boolean - estimatedCostReductionPerHourVolumeUsdNotNil: Boolean - - """estimated_cost_reduction_per_hour_usd field predicates""" - estimatedCostReductionPerHourUsd: Float - estimatedCostReductionPerHourUsdNEQ: Float - estimatedCostReductionPerHourUsdIn: [Float!] - estimatedCostReductionPerHourUsdNotIn: [Float!] - estimatedCostReductionPerHourUsdGT: Float - estimatedCostReductionPerHourUsdGTE: Float - estimatedCostReductionPerHourUsdLT: Float - estimatedCostReductionPerHourUsdLTE: Float - estimatedCostReductionPerHourUsdIsNil: Boolean - estimatedCostReductionPerHourUsdNotNil: Boolean + """current_events_per_hour field predicates""" + currentEventsPerHour: Float + currentEventsPerHourNEQ: Float + currentEventsPerHourIn: [Float!] + currentEventsPerHourNotIn: [Float!] + currentEventsPerHourGT: Float + currentEventsPerHourGTE: Float + currentEventsPerHourLT: Float + currentEventsPerHourLTE: Float + currentEventsPerHourIsNil: Boolean + currentEventsPerHourNotNil: Boolean + + """current_bytes_per_hour field predicates""" + currentBytesPerHour: Float + currentBytesPerHourNEQ: Float + currentBytesPerHourIn: [Float!] + currentBytesPerHourNotIn: [Float!] + currentBytesPerHourGT: Float + currentBytesPerHourGTE: Float + currentBytesPerHourLT: Float + currentBytesPerHourLTE: Float + currentBytesPerHourIsNil: Boolean + currentBytesPerHourNotNil: Boolean + + """current_bytes_usd_per_hour field predicates""" + currentBytesUsdPerHour: Float + currentBytesUsdPerHourNEQ: Float + currentBytesUsdPerHourIn: [Float!] + currentBytesUsdPerHourNotIn: [Float!] + currentBytesUsdPerHourGT: Float + currentBytesUsdPerHourGTE: Float + currentBytesUsdPerHourLT: Float + currentBytesUsdPerHourLTE: Float + currentBytesUsdPerHourIsNil: Boolean + currentBytesUsdPerHourNotNil: Boolean + + """current_volume_usd_per_hour field predicates""" + currentVolumeUsdPerHour: Float + currentVolumeUsdPerHourNEQ: Float + currentVolumeUsdPerHourIn: [Float!] + currentVolumeUsdPerHourNotIn: [Float!] + currentVolumeUsdPerHourGT: Float + currentVolumeUsdPerHourGTE: Float + currentVolumeUsdPerHourLT: Float + currentVolumeUsdPerHourLTE: Float + currentVolumeUsdPerHourIsNil: Boolean + currentVolumeUsdPerHourNotNil: Boolean + + """current_total_usd_per_hour field predicates""" + currentTotalUsdPerHour: Float + currentTotalUsdPerHourNEQ: Float + currentTotalUsdPerHourIn: [Float!] + currentTotalUsdPerHourNotIn: [Float!] + currentTotalUsdPerHourGT: Float + currentTotalUsdPerHourGTE: Float + currentTotalUsdPerHourLT: Float + currentTotalUsdPerHourLTE: Float + currentTotalUsdPerHourIsNil: Boolean + currentTotalUsdPerHourNotNil: Boolean + + """estimated_events_per_hour field predicates""" + estimatedEventsPerHour: Float + estimatedEventsPerHourNEQ: Float + estimatedEventsPerHourIn: [Float!] + estimatedEventsPerHourNotIn: [Float!] + estimatedEventsPerHourGT: Float + estimatedEventsPerHourGTE: Float + estimatedEventsPerHourLT: Float + estimatedEventsPerHourLTE: Float + estimatedEventsPerHourIsNil: Boolean + estimatedEventsPerHourNotNil: Boolean + + """estimated_bytes_per_hour field predicates""" + estimatedBytesPerHour: Float + estimatedBytesPerHourNEQ: Float + estimatedBytesPerHourIn: [Float!] + estimatedBytesPerHourNotIn: [Float!] + estimatedBytesPerHourGT: Float + estimatedBytesPerHourGTE: Float + estimatedBytesPerHourLT: Float + estimatedBytesPerHourLTE: Float + estimatedBytesPerHourIsNil: Boolean + estimatedBytesPerHourNotNil: Boolean + + """estimated_bytes_usd_per_hour field predicates""" + estimatedBytesUsdPerHour: Float + estimatedBytesUsdPerHourNEQ: Float + estimatedBytesUsdPerHourIn: [Float!] + estimatedBytesUsdPerHourNotIn: [Float!] + estimatedBytesUsdPerHourGT: Float + estimatedBytesUsdPerHourGTE: Float + estimatedBytesUsdPerHourLT: Float + estimatedBytesUsdPerHourLTE: Float + estimatedBytesUsdPerHourIsNil: Boolean + estimatedBytesUsdPerHourNotNil: Boolean + + """estimated_volume_usd_per_hour field predicates""" + estimatedVolumeUsdPerHour: Float + estimatedVolumeUsdPerHourNEQ: Float + estimatedVolumeUsdPerHourIn: [Float!] + estimatedVolumeUsdPerHourNotIn: [Float!] + estimatedVolumeUsdPerHourGT: Float + estimatedVolumeUsdPerHourGTE: Float + estimatedVolumeUsdPerHourLT: Float + estimatedVolumeUsdPerHourLTE: Float + estimatedVolumeUsdPerHourIsNil: Boolean + estimatedVolumeUsdPerHourNotNil: Boolean + + """estimated_total_usd_per_hour field predicates""" + estimatedTotalUsdPerHour: Float + estimatedTotalUsdPerHourNEQ: Float + estimatedTotalUsdPerHourIn: [Float!] + estimatedTotalUsdPerHourNotIn: [Float!] + estimatedTotalUsdPerHourGT: Float + estimatedTotalUsdPerHourGTE: Float + estimatedTotalUsdPerHourLT: Float + estimatedTotalUsdPerHourLTE: Float + estimatedTotalUsdPerHourIsNil: Boolean + estimatedTotalUsdPerHourNotNil: Boolean + + """impact_events_per_hour field predicates""" + impactEventsPerHour: Float + impactEventsPerHourNEQ: Float + impactEventsPerHourIn: [Float!] + impactEventsPerHourNotIn: [Float!] + impactEventsPerHourGT: Float + impactEventsPerHourGTE: Float + impactEventsPerHourLT: Float + impactEventsPerHourLTE: Float + impactEventsPerHourIsNil: Boolean + impactEventsPerHourNotNil: Boolean + + """impact_bytes_per_hour field predicates""" + impactBytesPerHour: Float + impactBytesPerHourNEQ: Float + impactBytesPerHourIn: [Float!] + impactBytesPerHourNotIn: [Float!] + impactBytesPerHourGT: Float + impactBytesPerHourGTE: Float + impactBytesPerHourLT: Float + impactBytesPerHourLTE: Float + impactBytesPerHourIsNil: Boolean + impactBytesPerHourNotNil: Boolean + + """impact_bytes_usd_per_hour field predicates""" + impactBytesUsdPerHour: Float + impactBytesUsdPerHourNEQ: Float + impactBytesUsdPerHourIn: [Float!] + impactBytesUsdPerHourNotIn: [Float!] + impactBytesUsdPerHourGT: Float + impactBytesUsdPerHourGTE: Float + impactBytesUsdPerHourLT: Float + impactBytesUsdPerHourLTE: Float + impactBytesUsdPerHourIsNil: Boolean + impactBytesUsdPerHourNotNil: Boolean + + """impact_volume_usd_per_hour field predicates""" + impactVolumeUsdPerHour: Float + impactVolumeUsdPerHourNEQ: Float + impactVolumeUsdPerHourIn: [Float!] + impactVolumeUsdPerHourNotIn: [Float!] + impactVolumeUsdPerHourGT: Float + impactVolumeUsdPerHourGTE: Float + impactVolumeUsdPerHourLT: Float + impactVolumeUsdPerHourLTE: Float + impactVolumeUsdPerHourIsNil: Boolean + impactVolumeUsdPerHourNotNil: Boolean + + """impact_total_usd_per_hour field predicates""" + impactTotalUsdPerHour: Float + impactTotalUsdPerHourNEQ: Float + impactTotalUsdPerHourIn: [Float!] + impactTotalUsdPerHourNotIn: [Float!] + impactTotalUsdPerHourGT: Float + impactTotalUsdPerHourGTE: Float + impactTotalUsdPerHourLT: Float + impactTotalUsdPerHourLTE: Float + impactTotalUsdPerHourIsNil: Boolean + impactTotalUsdPerHourNotNil: Boolean """service_id field predicates""" serviceID: UUID @@ -3209,30 +3727,6 @@ input LogEventPolicyStatusCacheWhereInput { logEventNameEqualFold: String logEventNameContainsFold: String - """volume_per_hour field predicates""" - volumePerHour: Float - volumePerHourNEQ: Float - volumePerHourIn: [Float!] - volumePerHourNotIn: [Float!] - volumePerHourGT: Float - volumePerHourGTE: Float - volumePerHourLT: Float - volumePerHourLTE: Float - volumePerHourIsNil: Boolean - volumePerHourNotNil: Boolean - - """bytes_per_hour field predicates""" - bytesPerHour: Float - bytesPerHourNEQ: Float - bytesPerHourIn: [Float!] - bytesPerHourNotIn: [Float!] - bytesPerHourGT: Float - bytesPerHourGTE: Float - bytesPerHourLT: Float - bytesPerHourLTE: Float - bytesPerHourIsNil: Boolean - bytesPerHourNotNil: Boolean - """refreshed_at field predicates""" refreshedAt: Time refreshedAtNEQ: Time @@ -3245,13 +3739,13 @@ input LogEventPolicyStatusCacheWhereInput { } """ -LogEventPolicyWhereInput is used for filtering LogEventPolicy objects. +LogEventRecommendationWhereInput is used for filtering LogEventRecommendation objects. Input was generated by ent. """ -input LogEventPolicyWhereInput { - not: LogEventPolicyWhereInput - and: [LogEventPolicyWhereInput!] - or: [LogEventPolicyWhereInput!] +input LogEventRecommendationWhereInput { + not: LogEventRecommendationWhereInput + and: [LogEventRecommendationWhereInput!] + or: [LogEventRecommendationWhereInput!] """id field predicates""" id: ID @@ -3286,34 +3780,34 @@ input LogEventPolicyWhereInput { workspaceIDNotIn: [ID!] """category field predicates""" - category: LogEventPolicyCategory - categoryNEQ: LogEventPolicyCategory - categoryIn: [LogEventPolicyCategory!] - categoryNotIn: [LogEventPolicyCategory!] + category: LogEventRecommendationCategory + categoryNEQ: LogEventRecommendationCategory + categoryIn: [LogEventRecommendationCategory!] + categoryNotIn: [LogEventRecommendationCategory!] """subjective field predicates""" subjective: Boolean subjectiveNEQ: Boolean """category_type field predicates""" - categoryType: LogEventPolicyCategoryType - categoryTypeNEQ: LogEventPolicyCategoryType - categoryTypeIn: [LogEventPolicyCategoryType!] - categoryTypeNotIn: [LogEventPolicyCategoryType!] + categoryType: LogEventRecommendationCategoryType + categoryTypeNEQ: LogEventRecommendationCategoryType + categoryTypeIn: [LogEventRecommendationCategoryType!] + categoryTypeNotIn: [LogEventRecommendationCategoryType!] """severity field predicates""" - severity: LogEventPolicySeverity - severityNEQ: LogEventPolicySeverity - severityIn: [LogEventPolicySeverity!] - severityNotIn: [LogEventPolicySeverity!] + severity: LogEventRecommendationSeverity + severityNEQ: LogEventRecommendationSeverity + severityIn: [LogEventRecommendationSeverity!] + severityNotIn: [LogEventRecommendationSeverity!] severityIsNil: Boolean severityNotNil: Boolean """action field predicates""" - action: LogEventPolicyAction - actionNEQ: LogEventPolicyAction - actionIn: [LogEventPolicyAction!] - actionNotIn: [LogEventPolicyAction!] + action: LogEventRecommendationAction + actionNEQ: LogEventRecommendationAction + actionIn: [LogEventRecommendationAction!] + actionNotIn: [LogEventRecommendationAction!] """approved_at field predicates""" approvedAt: Time @@ -3450,14 +3944,6 @@ enum LogEventSeverity { other } -"""LogEventSignalPurpose is enum for the field signal_purpose""" -enum LogEventSignalPurpose { - diagnostic - operational - lifecycle - ephemeral -} - type LogEventStatusCache implements Node { id: ID! accountID: UUID! @@ -3465,34 +3951,30 @@ type LogEventStatusCache implements Node { serviceID: UUID! hasVolumes: Boolean! hasBeenAnalyzed: Boolean! - policyCount: Int! - pendingPolicyCount: Int! - approvedPolicyCount: Int! - dismissedPolicyCount: Int! + effectivePolicyEnabled: Boolean! + recommendationCount: Int! + pendingRecommendationCount: Int! + approvedRecommendationCount: Int! + dismissedRecommendationCount: Int! policyPendingLowCount: Int! policyPendingMediumCount: Int! policyPendingHighCount: Int! policyPendingCriticalCount: Int! - estimatedVolumeReductionPerHour: Float - estimatedBytesReductionPerHour: Float - volumePerHour: Float - bytesPerHour: Float - costPerHourBytesUsd: Float - costPerHourVolumeUsd: Float - costPerHourUsd: Float - estimatedCostReductionPerHourBytesUsd: Float - estimatedCostReductionPerHourVolumeUsd: Float - estimatedCostReductionPerHourUsd: Float - observedVolumePerHourBefore: Float - observedVolumePerHourAfter: Float - observedBytesPerHourBefore: Float - observedBytesPerHourAfter: Float - observedCostPerHourBeforeBytesUsd: Float - observedCostPerHourBeforeVolumeUsd: Float - observedCostPerHourBeforeUsd: Float - observedCostPerHourAfterBytesUsd: Float - observedCostPerHourAfterVolumeUsd: Float - observedCostPerHourAfterUsd: Float + currentEventsPerHour: Float + currentBytesPerHour: Float + currentBytesUsdPerHour: Float + currentVolumeUsdPerHour: Float + currentTotalUsdPerHour: Float + estimatedEventsPerHour: Float + estimatedBytesPerHour: Float + estimatedBytesUsdPerHour: Float + estimatedVolumeUsdPerHour: Float + estimatedTotalUsdPerHour: Float + impactEventsPerHour: Float + impactBytesPerHour: Float + impactBytesUsdPerHour: Float + impactVolumeUsdPerHour: Float + impactTotalUsdPerHour: Float refreshedAt: Time! } @@ -3549,45 +4031,49 @@ input LogEventStatusCacheWhereInput { hasBeenAnalyzed: Boolean hasBeenAnalyzedNEQ: Boolean - """policy_count field predicates""" - policyCount: Int - policyCountNEQ: Int - policyCountIn: [Int!] - policyCountNotIn: [Int!] - policyCountGT: Int - policyCountGTE: Int - policyCountLT: Int - policyCountLTE: Int - - """pending_policy_count field predicates""" - pendingPolicyCount: Int - pendingPolicyCountNEQ: Int - pendingPolicyCountIn: [Int!] - pendingPolicyCountNotIn: [Int!] - pendingPolicyCountGT: Int - pendingPolicyCountGTE: Int - pendingPolicyCountLT: Int - pendingPolicyCountLTE: Int - - """approved_policy_count field predicates""" - approvedPolicyCount: Int - approvedPolicyCountNEQ: Int - approvedPolicyCountIn: [Int!] - approvedPolicyCountNotIn: [Int!] - approvedPolicyCountGT: Int - approvedPolicyCountGTE: Int - approvedPolicyCountLT: Int - approvedPolicyCountLTE: Int - - """dismissed_policy_count field predicates""" - dismissedPolicyCount: Int - dismissedPolicyCountNEQ: Int - dismissedPolicyCountIn: [Int!] - dismissedPolicyCountNotIn: [Int!] - dismissedPolicyCountGT: Int - dismissedPolicyCountGTE: Int - dismissedPolicyCountLT: Int - dismissedPolicyCountLTE: Int + """effective_policy_enabled field predicates""" + effectivePolicyEnabled: Boolean + effectivePolicyEnabledNEQ: Boolean + + """recommendation_count field predicates""" + recommendationCount: Int + recommendationCountNEQ: Int + recommendationCountIn: [Int!] + recommendationCountNotIn: [Int!] + recommendationCountGT: Int + recommendationCountGTE: Int + recommendationCountLT: Int + recommendationCountLTE: Int + + """pending_recommendation_count field predicates""" + pendingRecommendationCount: Int + pendingRecommendationCountNEQ: Int + pendingRecommendationCountIn: [Int!] + pendingRecommendationCountNotIn: [Int!] + pendingRecommendationCountGT: Int + pendingRecommendationCountGTE: Int + pendingRecommendationCountLT: Int + pendingRecommendationCountLTE: Int + + """approved_recommendation_count field predicates""" + approvedRecommendationCount: Int + approvedRecommendationCountNEQ: Int + approvedRecommendationCountIn: [Int!] + approvedRecommendationCountNotIn: [Int!] + approvedRecommendationCountGT: Int + approvedRecommendationCountGTE: Int + approvedRecommendationCountLT: Int + approvedRecommendationCountLTE: Int + + """dismissed_recommendation_count field predicates""" + dismissedRecommendationCount: Int + dismissedRecommendationCountNEQ: Int + dismissedRecommendationCountIn: [Int!] + dismissedRecommendationCountNotIn: [Int!] + dismissedRecommendationCountGT: Int + dismissedRecommendationCountGTE: Int + dismissedRecommendationCountLT: Int + dismissedRecommendationCountLTE: Int """policy_pending_low_count field predicates""" policyPendingLowCount: Int @@ -3629,245 +4115,185 @@ input LogEventStatusCacheWhereInput { policyPendingCriticalCountLT: Int policyPendingCriticalCountLTE: Int - """estimated_volume_reduction_per_hour field predicates""" - estimatedVolumeReductionPerHour: Float - estimatedVolumeReductionPerHourNEQ: Float - estimatedVolumeReductionPerHourIn: [Float!] - estimatedVolumeReductionPerHourNotIn: [Float!] - estimatedVolumeReductionPerHourGT: Float - estimatedVolumeReductionPerHourGTE: Float - estimatedVolumeReductionPerHourLT: Float - estimatedVolumeReductionPerHourLTE: Float - estimatedVolumeReductionPerHourIsNil: Boolean - estimatedVolumeReductionPerHourNotNil: Boolean - - """estimated_bytes_reduction_per_hour field predicates""" - estimatedBytesReductionPerHour: Float - estimatedBytesReductionPerHourNEQ: Float - estimatedBytesReductionPerHourIn: [Float!] - estimatedBytesReductionPerHourNotIn: [Float!] - estimatedBytesReductionPerHourGT: Float - estimatedBytesReductionPerHourGTE: Float - estimatedBytesReductionPerHourLT: Float - estimatedBytesReductionPerHourLTE: Float - estimatedBytesReductionPerHourIsNil: Boolean - estimatedBytesReductionPerHourNotNil: Boolean - - """volume_per_hour field predicates""" - volumePerHour: Float - volumePerHourNEQ: Float - volumePerHourIn: [Float!] - volumePerHourNotIn: [Float!] - volumePerHourGT: Float - volumePerHourGTE: Float - volumePerHourLT: Float - volumePerHourLTE: Float - volumePerHourIsNil: Boolean - volumePerHourNotNil: Boolean - - """bytes_per_hour field predicates""" - bytesPerHour: Float - bytesPerHourNEQ: Float - bytesPerHourIn: [Float!] - bytesPerHourNotIn: [Float!] - bytesPerHourGT: Float - bytesPerHourGTE: Float - bytesPerHourLT: Float - bytesPerHourLTE: Float - bytesPerHourIsNil: Boolean - bytesPerHourNotNil: Boolean - - """cost_per_hour_bytes_usd field predicates""" - costPerHourBytesUsd: Float - costPerHourBytesUsdNEQ: Float - costPerHourBytesUsdIn: [Float!] - costPerHourBytesUsdNotIn: [Float!] - costPerHourBytesUsdGT: Float - costPerHourBytesUsdGTE: Float - costPerHourBytesUsdLT: Float - costPerHourBytesUsdLTE: Float - costPerHourBytesUsdIsNil: Boolean - costPerHourBytesUsdNotNil: Boolean - - """cost_per_hour_volume_usd field predicates""" - costPerHourVolumeUsd: Float - costPerHourVolumeUsdNEQ: Float - costPerHourVolumeUsdIn: [Float!] - costPerHourVolumeUsdNotIn: [Float!] - costPerHourVolumeUsdGT: Float - costPerHourVolumeUsdGTE: Float - costPerHourVolumeUsdLT: Float - costPerHourVolumeUsdLTE: Float - costPerHourVolumeUsdIsNil: Boolean - costPerHourVolumeUsdNotNil: Boolean - - """cost_per_hour_usd field predicates""" - costPerHourUsd: Float - costPerHourUsdNEQ: Float - costPerHourUsdIn: [Float!] - costPerHourUsdNotIn: [Float!] - costPerHourUsdGT: Float - costPerHourUsdGTE: Float - costPerHourUsdLT: Float - costPerHourUsdLTE: Float - costPerHourUsdIsNil: Boolean - costPerHourUsdNotNil: Boolean - - """estimated_cost_reduction_per_hour_bytes_usd field predicates""" - estimatedCostReductionPerHourBytesUsd: Float - estimatedCostReductionPerHourBytesUsdNEQ: Float - estimatedCostReductionPerHourBytesUsdIn: [Float!] - estimatedCostReductionPerHourBytesUsdNotIn: [Float!] - estimatedCostReductionPerHourBytesUsdGT: Float - estimatedCostReductionPerHourBytesUsdGTE: Float - estimatedCostReductionPerHourBytesUsdLT: Float - estimatedCostReductionPerHourBytesUsdLTE: Float - estimatedCostReductionPerHourBytesUsdIsNil: Boolean - estimatedCostReductionPerHourBytesUsdNotNil: Boolean - - """estimated_cost_reduction_per_hour_volume_usd field predicates""" - estimatedCostReductionPerHourVolumeUsd: Float - estimatedCostReductionPerHourVolumeUsdNEQ: Float - estimatedCostReductionPerHourVolumeUsdIn: [Float!] - estimatedCostReductionPerHourVolumeUsdNotIn: [Float!] - estimatedCostReductionPerHourVolumeUsdGT: Float - estimatedCostReductionPerHourVolumeUsdGTE: Float - estimatedCostReductionPerHourVolumeUsdLT: Float - estimatedCostReductionPerHourVolumeUsdLTE: Float - estimatedCostReductionPerHourVolumeUsdIsNil: Boolean - estimatedCostReductionPerHourVolumeUsdNotNil: Boolean - - """estimated_cost_reduction_per_hour_usd field predicates""" - estimatedCostReductionPerHourUsd: Float - estimatedCostReductionPerHourUsdNEQ: Float - estimatedCostReductionPerHourUsdIn: [Float!] - estimatedCostReductionPerHourUsdNotIn: [Float!] - estimatedCostReductionPerHourUsdGT: Float - estimatedCostReductionPerHourUsdGTE: Float - estimatedCostReductionPerHourUsdLT: Float - estimatedCostReductionPerHourUsdLTE: Float - estimatedCostReductionPerHourUsdIsNil: Boolean - estimatedCostReductionPerHourUsdNotNil: Boolean - - """observed_volume_per_hour_before field predicates""" - observedVolumePerHourBefore: Float - observedVolumePerHourBeforeNEQ: Float - observedVolumePerHourBeforeIn: [Float!] - observedVolumePerHourBeforeNotIn: [Float!] - observedVolumePerHourBeforeGT: Float - observedVolumePerHourBeforeGTE: Float - observedVolumePerHourBeforeLT: Float - observedVolumePerHourBeforeLTE: Float - observedVolumePerHourBeforeIsNil: Boolean - observedVolumePerHourBeforeNotNil: Boolean - - """observed_volume_per_hour_after field predicates""" - observedVolumePerHourAfter: Float - observedVolumePerHourAfterNEQ: Float - observedVolumePerHourAfterIn: [Float!] - observedVolumePerHourAfterNotIn: [Float!] - observedVolumePerHourAfterGT: Float - observedVolumePerHourAfterGTE: Float - observedVolumePerHourAfterLT: Float - observedVolumePerHourAfterLTE: Float - observedVolumePerHourAfterIsNil: Boolean - observedVolumePerHourAfterNotNil: Boolean - - """observed_bytes_per_hour_before field predicates""" - observedBytesPerHourBefore: Float - observedBytesPerHourBeforeNEQ: Float - observedBytesPerHourBeforeIn: [Float!] - observedBytesPerHourBeforeNotIn: [Float!] - observedBytesPerHourBeforeGT: Float - observedBytesPerHourBeforeGTE: Float - observedBytesPerHourBeforeLT: Float - observedBytesPerHourBeforeLTE: Float - observedBytesPerHourBeforeIsNil: Boolean - observedBytesPerHourBeforeNotNil: Boolean - - """observed_bytes_per_hour_after field predicates""" - observedBytesPerHourAfter: Float - observedBytesPerHourAfterNEQ: Float - observedBytesPerHourAfterIn: [Float!] - observedBytesPerHourAfterNotIn: [Float!] - observedBytesPerHourAfterGT: Float - observedBytesPerHourAfterGTE: Float - observedBytesPerHourAfterLT: Float - observedBytesPerHourAfterLTE: Float - observedBytesPerHourAfterIsNil: Boolean - observedBytesPerHourAfterNotNil: Boolean - - """observed_cost_per_hour_before_bytes_usd field predicates""" - observedCostPerHourBeforeBytesUsd: Float - observedCostPerHourBeforeBytesUsdNEQ: Float - observedCostPerHourBeforeBytesUsdIn: [Float!] - observedCostPerHourBeforeBytesUsdNotIn: [Float!] - observedCostPerHourBeforeBytesUsdGT: Float - observedCostPerHourBeforeBytesUsdGTE: Float - observedCostPerHourBeforeBytesUsdLT: Float - observedCostPerHourBeforeBytesUsdLTE: Float - observedCostPerHourBeforeBytesUsdIsNil: Boolean - observedCostPerHourBeforeBytesUsdNotNil: Boolean - - """observed_cost_per_hour_before_volume_usd field predicates""" - observedCostPerHourBeforeVolumeUsd: Float - observedCostPerHourBeforeVolumeUsdNEQ: Float - observedCostPerHourBeforeVolumeUsdIn: [Float!] - observedCostPerHourBeforeVolumeUsdNotIn: [Float!] - observedCostPerHourBeforeVolumeUsdGT: Float - observedCostPerHourBeforeVolumeUsdGTE: Float - observedCostPerHourBeforeVolumeUsdLT: Float - observedCostPerHourBeforeVolumeUsdLTE: Float - observedCostPerHourBeforeVolumeUsdIsNil: Boolean - observedCostPerHourBeforeVolumeUsdNotNil: Boolean - - """observed_cost_per_hour_before_usd field predicates""" - observedCostPerHourBeforeUsd: Float - observedCostPerHourBeforeUsdNEQ: Float - observedCostPerHourBeforeUsdIn: [Float!] - observedCostPerHourBeforeUsdNotIn: [Float!] - observedCostPerHourBeforeUsdGT: Float - observedCostPerHourBeforeUsdGTE: Float - observedCostPerHourBeforeUsdLT: Float - observedCostPerHourBeforeUsdLTE: Float - observedCostPerHourBeforeUsdIsNil: Boolean - observedCostPerHourBeforeUsdNotNil: Boolean - - """observed_cost_per_hour_after_bytes_usd field predicates""" - observedCostPerHourAfterBytesUsd: Float - observedCostPerHourAfterBytesUsdNEQ: Float - observedCostPerHourAfterBytesUsdIn: [Float!] - observedCostPerHourAfterBytesUsdNotIn: [Float!] - observedCostPerHourAfterBytesUsdGT: Float - observedCostPerHourAfterBytesUsdGTE: Float - observedCostPerHourAfterBytesUsdLT: Float - observedCostPerHourAfterBytesUsdLTE: Float - observedCostPerHourAfterBytesUsdIsNil: Boolean - observedCostPerHourAfterBytesUsdNotNil: Boolean - - """observed_cost_per_hour_after_volume_usd field predicates""" - observedCostPerHourAfterVolumeUsd: Float - observedCostPerHourAfterVolumeUsdNEQ: Float - observedCostPerHourAfterVolumeUsdIn: [Float!] - observedCostPerHourAfterVolumeUsdNotIn: [Float!] - observedCostPerHourAfterVolumeUsdGT: Float - observedCostPerHourAfterVolumeUsdGTE: Float - observedCostPerHourAfterVolumeUsdLT: Float - observedCostPerHourAfterVolumeUsdLTE: Float - observedCostPerHourAfterVolumeUsdIsNil: Boolean - observedCostPerHourAfterVolumeUsdNotNil: Boolean - - """observed_cost_per_hour_after_usd field predicates""" - observedCostPerHourAfterUsd: Float - observedCostPerHourAfterUsdNEQ: Float - observedCostPerHourAfterUsdIn: [Float!] - observedCostPerHourAfterUsdNotIn: [Float!] - observedCostPerHourAfterUsdGT: Float - observedCostPerHourAfterUsdGTE: Float - observedCostPerHourAfterUsdLT: Float - observedCostPerHourAfterUsdLTE: Float - observedCostPerHourAfterUsdIsNil: Boolean - observedCostPerHourAfterUsdNotNil: Boolean + """current_events_per_hour field predicates""" + currentEventsPerHour: Float + currentEventsPerHourNEQ: Float + currentEventsPerHourIn: [Float!] + currentEventsPerHourNotIn: [Float!] + currentEventsPerHourGT: Float + currentEventsPerHourGTE: Float + currentEventsPerHourLT: Float + currentEventsPerHourLTE: Float + currentEventsPerHourIsNil: Boolean + currentEventsPerHourNotNil: Boolean + + """current_bytes_per_hour field predicates""" + currentBytesPerHour: Float + currentBytesPerHourNEQ: Float + currentBytesPerHourIn: [Float!] + currentBytesPerHourNotIn: [Float!] + currentBytesPerHourGT: Float + currentBytesPerHourGTE: Float + currentBytesPerHourLT: Float + currentBytesPerHourLTE: Float + currentBytesPerHourIsNil: Boolean + currentBytesPerHourNotNil: Boolean + + """current_bytes_usd_per_hour field predicates""" + currentBytesUsdPerHour: Float + currentBytesUsdPerHourNEQ: Float + currentBytesUsdPerHourIn: [Float!] + currentBytesUsdPerHourNotIn: [Float!] + currentBytesUsdPerHourGT: Float + currentBytesUsdPerHourGTE: Float + currentBytesUsdPerHourLT: Float + currentBytesUsdPerHourLTE: Float + currentBytesUsdPerHourIsNil: Boolean + currentBytesUsdPerHourNotNil: Boolean + + """current_volume_usd_per_hour field predicates""" + currentVolumeUsdPerHour: Float + currentVolumeUsdPerHourNEQ: Float + currentVolumeUsdPerHourIn: [Float!] + currentVolumeUsdPerHourNotIn: [Float!] + currentVolumeUsdPerHourGT: Float + currentVolumeUsdPerHourGTE: Float + currentVolumeUsdPerHourLT: Float + currentVolumeUsdPerHourLTE: Float + currentVolumeUsdPerHourIsNil: Boolean + currentVolumeUsdPerHourNotNil: Boolean + + """current_total_usd_per_hour field predicates""" + currentTotalUsdPerHour: Float + currentTotalUsdPerHourNEQ: Float + currentTotalUsdPerHourIn: [Float!] + currentTotalUsdPerHourNotIn: [Float!] + currentTotalUsdPerHourGT: Float + currentTotalUsdPerHourGTE: Float + currentTotalUsdPerHourLT: Float + currentTotalUsdPerHourLTE: Float + currentTotalUsdPerHourIsNil: Boolean + currentTotalUsdPerHourNotNil: Boolean + + """estimated_events_per_hour field predicates""" + estimatedEventsPerHour: Float + estimatedEventsPerHourNEQ: Float + estimatedEventsPerHourIn: [Float!] + estimatedEventsPerHourNotIn: [Float!] + estimatedEventsPerHourGT: Float + estimatedEventsPerHourGTE: Float + estimatedEventsPerHourLT: Float + estimatedEventsPerHourLTE: Float + estimatedEventsPerHourIsNil: Boolean + estimatedEventsPerHourNotNil: Boolean + + """estimated_bytes_per_hour field predicates""" + estimatedBytesPerHour: Float + estimatedBytesPerHourNEQ: Float + estimatedBytesPerHourIn: [Float!] + estimatedBytesPerHourNotIn: [Float!] + estimatedBytesPerHourGT: Float + estimatedBytesPerHourGTE: Float + estimatedBytesPerHourLT: Float + estimatedBytesPerHourLTE: Float + estimatedBytesPerHourIsNil: Boolean + estimatedBytesPerHourNotNil: Boolean + + """estimated_bytes_usd_per_hour field predicates""" + estimatedBytesUsdPerHour: Float + estimatedBytesUsdPerHourNEQ: Float + estimatedBytesUsdPerHourIn: [Float!] + estimatedBytesUsdPerHourNotIn: [Float!] + estimatedBytesUsdPerHourGT: Float + estimatedBytesUsdPerHourGTE: Float + estimatedBytesUsdPerHourLT: Float + estimatedBytesUsdPerHourLTE: Float + estimatedBytesUsdPerHourIsNil: Boolean + estimatedBytesUsdPerHourNotNil: Boolean + + """estimated_volume_usd_per_hour field predicates""" + estimatedVolumeUsdPerHour: Float + estimatedVolumeUsdPerHourNEQ: Float + estimatedVolumeUsdPerHourIn: [Float!] + estimatedVolumeUsdPerHourNotIn: [Float!] + estimatedVolumeUsdPerHourGT: Float + estimatedVolumeUsdPerHourGTE: Float + estimatedVolumeUsdPerHourLT: Float + estimatedVolumeUsdPerHourLTE: Float + estimatedVolumeUsdPerHourIsNil: Boolean + estimatedVolumeUsdPerHourNotNil: Boolean + + """estimated_total_usd_per_hour field predicates""" + estimatedTotalUsdPerHour: Float + estimatedTotalUsdPerHourNEQ: Float + estimatedTotalUsdPerHourIn: [Float!] + estimatedTotalUsdPerHourNotIn: [Float!] + estimatedTotalUsdPerHourGT: Float + estimatedTotalUsdPerHourGTE: Float + estimatedTotalUsdPerHourLT: Float + estimatedTotalUsdPerHourLTE: Float + estimatedTotalUsdPerHourIsNil: Boolean + estimatedTotalUsdPerHourNotNil: Boolean + + """impact_events_per_hour field predicates""" + impactEventsPerHour: Float + impactEventsPerHourNEQ: Float + impactEventsPerHourIn: [Float!] + impactEventsPerHourNotIn: [Float!] + impactEventsPerHourGT: Float + impactEventsPerHourGTE: Float + impactEventsPerHourLT: Float + impactEventsPerHourLTE: Float + impactEventsPerHourIsNil: Boolean + impactEventsPerHourNotNil: Boolean + + """impact_bytes_per_hour field predicates""" + impactBytesPerHour: Float + impactBytesPerHourNEQ: Float + impactBytesPerHourIn: [Float!] + impactBytesPerHourNotIn: [Float!] + impactBytesPerHourGT: Float + impactBytesPerHourGTE: Float + impactBytesPerHourLT: Float + impactBytesPerHourLTE: Float + impactBytesPerHourIsNil: Boolean + impactBytesPerHourNotNil: Boolean + + """impact_bytes_usd_per_hour field predicates""" + impactBytesUsdPerHour: Float + impactBytesUsdPerHourNEQ: Float + impactBytesUsdPerHourIn: [Float!] + impactBytesUsdPerHourNotIn: [Float!] + impactBytesUsdPerHourGT: Float + impactBytesUsdPerHourGTE: Float + impactBytesUsdPerHourLT: Float + impactBytesUsdPerHourLTE: Float + impactBytesUsdPerHourIsNil: Boolean + impactBytesUsdPerHourNotNil: Boolean + + """impact_volume_usd_per_hour field predicates""" + impactVolumeUsdPerHour: Float + impactVolumeUsdPerHourNEQ: Float + impactVolumeUsdPerHourIn: [Float!] + impactVolumeUsdPerHourNotIn: [Float!] + impactVolumeUsdPerHourGT: Float + impactVolumeUsdPerHourGTE: Float + impactVolumeUsdPerHourLT: Float + impactVolumeUsdPerHourLTE: Float + impactVolumeUsdPerHourIsNil: Boolean + impactVolumeUsdPerHourNotNil: Boolean + + """impact_total_usd_per_hour field predicates""" + impactTotalUsdPerHour: Float + impactTotalUsdPerHourNEQ: Float + impactTotalUsdPerHourIn: [Float!] + impactTotalUsdPerHourNotIn: [Float!] + impactTotalUsdPerHourGT: Float + impactTotalUsdPerHourGTE: Float + impactTotalUsdPerHourLT: Float + impactTotalUsdPerHourLTE: Float + impactTotalUsdPerHourIsNil: Boolean + impactTotalUsdPerHourNotNil: Boolean """refreshed_at field predicates""" refreshedAt: Time @@ -3953,18 +4379,6 @@ input LogEventWhereInput { severityIsNil: Boolean severityNotNil: Boolean - """signal_purpose field predicates""" - signalPurpose: LogEventSignalPurpose - signalPurposeNEQ: LogEventSignalPurpose - signalPurposeIn: [LogEventSignalPurpose!] - signalPurposeNotIn: [LogEventSignalPurpose!] - - """event_nature field predicates""" - eventNature: LogEventEventNature - eventNatureNEQ: LogEventEventNature - eventNatureIn: [LogEventEventNature!] - eventNatureNotIn: [LogEventEventNature!] - """is_fragment field predicates""" isFragment: Boolean isFragmentNEQ: Boolean @@ -4023,11 +4437,15 @@ input LogEventWhereInput { """policies edge predicates""" hasPolicies: Boolean - hasPoliciesWith: [LogEventPolicyWhereInput!] + hasPoliciesWith: [LogEventRecommendationWhereInput!] """log_event_fields edge predicates""" hasLogEventFields: Boolean hasLogEventFieldsWith: [LogEventFieldWhereInput!] + + """facts edge predicates""" + hasFacts: Boolean + hasFactsWith: [LogEventFactWhereInput!] } """A normalized log record following OTEL conventions""" @@ -4403,18 +4821,18 @@ input MessageWhereInput { type Mutation { createAccount(input: CreateAccountInput!): Account! updateAccount(id: ID!, input: UpdateAccountInput!): Account! - deleteAccount(id: ID!): Boolean! + deleteAccount(id: ID!, confirmation: String!): Boolean! createOrganization(input: CreateOrganizationInput!): Organization! createOrganizationAndBootstrap(input: CreateOrganizationInput!): OrganizationBootstrapResult! updateOrganization(id: ID!, input: UpdateOrganizationInput!): Organization! - deleteOrganization(id: ID!, confirmed: Boolean!): Boolean! + deleteOrganization(id: ID!, confirmation: String!): Boolean! createDatadogAccount(input: CreateDatadogAccountWithCredentialsInput!): DatadogAccount! updateDatadogAccount(id: ID!, input: UpdateDatadogAccountInput!): DatadogAccount! deleteDatadogAccount(id: ID!): Boolean! validateDatadogApiKey(input: ValidateDatadogApiKeyInput!): ValidateDatadogApiKeyResult! createWorkspace(input: CreateWorkspaceInput!): Workspace! updateWorkspace(id: ID!, input: UpdateWorkspaceInput!): Workspace! - deleteWorkspace(id: ID!): Boolean! + deleteWorkspace(id: ID!, confirmation: String!): Boolean! createTeam(input: CreateTeamInput!): Team! updateTeam(id: ID!, input: UpdateTeamInput!): Team! deleteTeam(id: ID!): Boolean! @@ -4465,18 +4883,18 @@ type Mutation { Approve a log event policy, enabling it for enforcement. Clears any previous dismissal. """ - approveLogEventPolicy(id: ID!): LogEventPolicy! + approveLogEventRecommendation(id: ID!, targets: EnforcementTargetInput!): LogEventRecommendation! """ Dismiss a log event policy, hiding it from pending review. Clears any previous approval. """ - dismissLogEventPolicy(id: ID!): LogEventPolicy! + dismissLogEventRecommendation(id: ID!): LogEventRecommendation! """ Reset a log event policy to pending, clearing any approval or dismissal. """ - resetLogEventPolicy(id: ID!): LogEventPolicy! + resetLogEventRecommendation(id: ID!): LogEventRecommendation! } """ @@ -4822,9 +5240,9 @@ type Query { ): LogEventConnection! """ - Query log event policies. Each policy is a category-specific recommendation. + Query log event recommendations. Each recommendation is category-specific. """ - logEventPolicies( + logEventRecommendations( """Returns the elements in the list that come after the specified cursor.""" after: Cursor @@ -4839,12 +5257,16 @@ type Query { """Returns the last _n_ elements from the list.""" last: Int - """Ordering options for LogEventPolicies returned from the connection.""" - orderBy: LogEventPolicyOrder + """ + Ordering options for LogEventRecommendations returned from the connection. + """ + orderBy: LogEventRecommendationOrder - """Filtering options for LogEventPolicies returned from the connection.""" - where: LogEventPolicyWhereInput - ): LogEventPolicyConnection! + """ + Filtering options for LogEventRecommendations returned from the connection. + """ + where: LogEventRecommendationWhereInput + ): LogEventRecommendationConnection! """Query messages in chat conversations.""" messages( @@ -5020,6 +5442,11 @@ type Query { viewer: Viewer! } +input ResourceSelectorInput { + key: String! + value: String! +} + type Service implements Node { """Unique identifier of the service""" id: ID! @@ -5039,7 +5466,7 @@ type Service implements Node { enabled: Boolean! """ - Approximate weekly log count from initial discovery (7-day period from Datadog) + Approximate weekly log count from initial catalog loop pass (7-day period from Datadog) """ initialWeeklyLogCount: Int @@ -5057,7 +5484,7 @@ type Service implements Node { """ Status of this service from a specific Datadog account. - Shows where the service is in the discovery pipeline. + Shows where the service is in the catalog pipeline. Returns null if cache has not been populated yet. """ status(datadogAccountID: ID!): ServiceStatusCache @@ -5084,6 +5511,276 @@ type ServiceEdge { cursor: Cursor! } +type ServiceLogField implements Node { + """Unique identifier""" + id: ID! + + """ + Denormalized for tenant isolation. Auto-set via trigger from service.account_id. + """ + accountID: ID! + + """Service this shared field belongs to""" + serviceID: ID! + + """Which shared field root this definition belongs to.""" + fieldRoot: ServiceLogFieldFieldRoot! + + """ + Unambiguous path segments for the shared field, e.g. {resource_attributes, service, name}. + """ + fieldPath: [String!]! + + """When this shared field was last seen on a log event for the service.""" + lastSeenAt: Time! + + """When this shared field was first discovered.""" + createdAt: Time! + + """When this shared field metadata was last updated.""" + updatedAt: Time! + + """Account this shared field belongs to""" + account: Account! + + """Service this shared field belongs to""" + service: Service! + + """Typed facts attached to this shared service field""" + facts: [ServiceLogFieldFact!] +} + +type ServiceLogFieldFact implements Node { + """Unique identifier""" + id: ID! + + """ + Denormalized for tenant isolation. Auto-set via trigger from service_log_field.account_id. + """ + accountID: UUID! + + """The shared service log field this fact belongs to""" + serviceLogFieldID: ID! + + """Fact namespace, e.g. structure, semantic, or quality.""" + namespace: String! + + """Fact type within the namespace, e.g. field_role or value_profile.""" + factType: String! + + """When this fact was first recorded""" + createdAt: Time! + + """When this fact was last refreshed""" + updatedAt: Time! + + """The shared service log field this fact belongs to""" + serviceLogField: ServiceLogField! +} + +"""Ordering options for ServiceLogFieldFact connections""" +input ServiceLogFieldFactOrder { + """The ordering direction.""" + direction: OrderDirection! = ASC + + """The field by which to order ServiceLogFieldFacts.""" + field: ServiceLogFieldFactOrderField! +} + +"""Properties by which ServiceLogFieldFact connections can be ordered.""" +enum ServiceLogFieldFactOrderField { + NAMESPACE + FACT_TYPE + CREATED_AT + UPDATED_AT +} + +""" +ServiceLogFieldFactWhereInput is used for filtering ServiceLogFieldFact objects. +Input was generated by ent. +""" +input ServiceLogFieldFactWhereInput { + not: ServiceLogFieldFactWhereInput + and: [ServiceLogFieldFactWhereInput!] + or: [ServiceLogFieldFactWhereInput!] + + """id field predicates""" + id: ID + idNEQ: ID + idIn: [ID!] + idNotIn: [ID!] + idGT: ID + idGTE: ID + idLT: ID + idLTE: ID + + """account_id field predicates""" + accountID: UUID + accountIDNEQ: UUID + accountIDIn: [UUID!] + accountIDNotIn: [UUID!] + accountIDGT: UUID + accountIDGTE: UUID + accountIDLT: UUID + accountIDLTE: UUID + + """service_log_field_id field predicates""" + serviceLogFieldID: ID + serviceLogFieldIDNEQ: ID + serviceLogFieldIDIn: [ID!] + serviceLogFieldIDNotIn: [ID!] + + """namespace field predicates""" + namespace: String + namespaceNEQ: String + namespaceIn: [String!] + namespaceNotIn: [String!] + namespaceGT: String + namespaceGTE: String + namespaceLT: String + namespaceLTE: String + namespaceContains: String + namespaceHasPrefix: String + namespaceHasSuffix: String + namespaceEqualFold: String + namespaceContainsFold: String + + """fact_type field predicates""" + factType: String + factTypeNEQ: String + factTypeIn: [String!] + factTypeNotIn: [String!] + factTypeGT: String + factTypeGTE: String + factTypeLT: String + factTypeLTE: String + factTypeContains: String + factTypeHasPrefix: String + factTypeHasSuffix: String + factTypeEqualFold: String + factTypeContainsFold: String + + """created_at field predicates""" + createdAt: Time + createdAtNEQ: Time + createdAtIn: [Time!] + createdAtNotIn: [Time!] + createdAtGT: Time + createdAtGTE: Time + createdAtLT: Time + createdAtLTE: Time + + """updated_at field predicates""" + updatedAt: Time + updatedAtNEQ: Time + updatedAtIn: [Time!] + updatedAtNotIn: [Time!] + updatedAtGT: Time + updatedAtGTE: Time + updatedAtLT: Time + updatedAtLTE: Time + + """service_log_field edge predicates""" + hasServiceLogField: Boolean + hasServiceLogFieldWith: [ServiceLogFieldWhereInput!] +} + +"""ServiceLogFieldFieldRoot is enum for the field field_root""" +enum ServiceLogFieldFieldRoot { + resource_attributes + scope_attributes +} + +""" +ServiceLogFieldWhereInput is used for filtering ServiceLogField objects. +Input was generated by ent. +""" +input ServiceLogFieldWhereInput { + not: ServiceLogFieldWhereInput + and: [ServiceLogFieldWhereInput!] + or: [ServiceLogFieldWhereInput!] + + """id field predicates""" + id: ID + idNEQ: ID + idIn: [ID!] + idNotIn: [ID!] + idGT: ID + idGTE: ID + idLT: ID + idLTE: ID + + """account_id field predicates""" + accountID: ID + accountIDNEQ: ID + accountIDIn: [ID!] + accountIDNotIn: [ID!] + + """service_id field predicates""" + serviceID: ID + serviceIDNEQ: ID + serviceIDIn: [ID!] + serviceIDNotIn: [ID!] + + """field_root field predicates""" + fieldRoot: ServiceLogFieldFieldRoot + fieldRootNEQ: ServiceLogFieldFieldRoot + fieldRootIn: [ServiceLogFieldFieldRoot!] + fieldRootNotIn: [ServiceLogFieldFieldRoot!] + + """field_path field predicates""" + fieldPath: [String!] + fieldPathNEQ: [String!] + fieldPathIn: [[String!]!] + fieldPathNotIn: [[String!]!] + fieldPathGT: [String!] + fieldPathGTE: [String!] + fieldPathLT: [String!] + fieldPathLTE: [String!] + + """last_seen_at field predicates""" + lastSeenAt: Time + lastSeenAtNEQ: Time + lastSeenAtIn: [Time!] + lastSeenAtNotIn: [Time!] + lastSeenAtGT: Time + lastSeenAtGTE: Time + lastSeenAtLT: Time + lastSeenAtLTE: Time + + """created_at field predicates""" + createdAt: Time + createdAtNEQ: Time + createdAtIn: [Time!] + createdAtNotIn: [Time!] + createdAtGT: Time + createdAtGTE: Time + createdAtLT: Time + createdAtLTE: Time + + """updated_at field predicates""" + updatedAt: Time + updatedAtNEQ: Time + updatedAtIn: [Time!] + updatedAtNotIn: [Time!] + updatedAtGT: Time + updatedAtGTE: Time + updatedAtLT: Time + updatedAtLTE: Time + + """account edge predicates""" + hasAccount: Boolean + hasAccountWith: [AccountWhereInput!] + + """service edge predicates""" + hasService: Boolean + hasServiceWith: [ServiceWhereInput!] + + """facts edge predicates""" + hasFacts: Boolean + hasFactsWith: [ServiceLogFieldFactWhereInput!] +} + """Ordering options for Service connections""" input ServiceOrder { """The ordering direction.""" @@ -5107,47 +5804,39 @@ type ServiceStatusCache implements Node { serviceID: ID! accountID: UUID! datadogAccountID: ID! - - """ - Overall health of the service. DISABLED (integration turned off), INACTIVE (no data received), OK (healthy). - """ health: ServiceStatusCacheHealth! logEventCount: Int! logEventAnalyzedCount: Int! - policyPendingCount: Int! - policyApprovedCount: Int! - policyDismissedCount: Int! + recommendationCount: Int! + pendingRecommendationCount: Int! + approvedRecommendationCount: Int! + dismissedRecommendationCount: Int! policyPendingLowCount: Int! policyPendingMediumCount: Int! policyPendingHighCount: Int! policyPendingCriticalCount: Int! - serviceVolumePerHour: Float - serviceDebugVolumePerHour: Float - serviceInfoVolumePerHour: Float - serviceWarnVolumePerHour: Float - serviceErrorVolumePerHour: Float - serviceOtherVolumePerHour: Float - serviceCostPerHourVolumeUsd: Float - logEventVolumePerHour: Float - logEventBytesPerHour: Float - logEventCostPerHourBytesUsd: Float - logEventCostPerHourVolumeUsd: Float - logEventCostPerHourUsd: Float - estimatedVolumeReductionPerHour: Float - estimatedBytesReductionPerHour: Float - estimatedCostReductionPerHourBytesUsd: Float - estimatedCostReductionPerHourVolumeUsd: Float - estimatedCostReductionPerHourUsd: Float - observedVolumePerHourBefore: Float - observedVolumePerHourAfter: Float - observedBytesPerHourBefore: Float - observedBytesPerHourAfter: Float - observedCostPerHourBeforeBytesUsd: Float - observedCostPerHourBeforeVolumeUsd: Float - observedCostPerHourBeforeUsd: Float - observedCostPerHourAfterBytesUsd: Float - observedCostPerHourAfterVolumeUsd: Float - observedCostPerHourAfterUsd: Float + currentServiceEventsPerHour: Float + currentServiceDebugEventsPerHour: Float + currentServiceInfoEventsPerHour: Float + currentServiceWarnEventsPerHour: Float + currentServiceErrorEventsPerHour: Float + currentServiceOtherEventsPerHour: Float + currentServiceVolumeUsdPerHour: Float + currentEventsPerHour: Float + currentBytesPerHour: Float + currentBytesUsdPerHour: Float + currentVolumeUsdPerHour: Float + currentTotalUsdPerHour: Float + estimatedEventsPerHour: Float + estimatedBytesPerHour: Float + estimatedBytesUsdPerHour: Float + estimatedVolumeUsdPerHour: Float + estimatedTotalUsdPerHour: Float + impactEventsPerHour: Float + impactBytesPerHour: Float + impactBytesUsdPerHour: Float + impactVolumeUsdPerHour: Float + impactTotalUsdPerHour: Float refreshedAt: Time! } @@ -5226,35 +5915,45 @@ input ServiceStatusCacheWhereInput { logEventAnalyzedCountLT: Int logEventAnalyzedCountLTE: Int - """policy_pending_count field predicates""" - policyPendingCount: Int - policyPendingCountNEQ: Int - policyPendingCountIn: [Int!] - policyPendingCountNotIn: [Int!] - policyPendingCountGT: Int - policyPendingCountGTE: Int - policyPendingCountLT: Int - policyPendingCountLTE: Int - - """policy_approved_count field predicates""" - policyApprovedCount: Int - policyApprovedCountNEQ: Int - policyApprovedCountIn: [Int!] - policyApprovedCountNotIn: [Int!] - policyApprovedCountGT: Int - policyApprovedCountGTE: Int - policyApprovedCountLT: Int - policyApprovedCountLTE: Int - - """policy_dismissed_count field predicates""" - policyDismissedCount: Int - policyDismissedCountNEQ: Int - policyDismissedCountIn: [Int!] - policyDismissedCountNotIn: [Int!] - policyDismissedCountGT: Int - policyDismissedCountGTE: Int - policyDismissedCountLT: Int - policyDismissedCountLTE: Int + """recommendation_count field predicates""" + recommendationCount: Int + recommendationCountNEQ: Int + recommendationCountIn: [Int!] + recommendationCountNotIn: [Int!] + recommendationCountGT: Int + recommendationCountGTE: Int + recommendationCountLT: Int + recommendationCountLTE: Int + + """pending_recommendation_count field predicates""" + pendingRecommendationCount: Int + pendingRecommendationCountNEQ: Int + pendingRecommendationCountIn: [Int!] + pendingRecommendationCountNotIn: [Int!] + pendingRecommendationCountGT: Int + pendingRecommendationCountGTE: Int + pendingRecommendationCountLT: Int + pendingRecommendationCountLTE: Int + + """approved_recommendation_count field predicates""" + approvedRecommendationCount: Int + approvedRecommendationCountNEQ: Int + approvedRecommendationCountIn: [Int!] + approvedRecommendationCountNotIn: [Int!] + approvedRecommendationCountGT: Int + approvedRecommendationCountGTE: Int + approvedRecommendationCountLT: Int + approvedRecommendationCountLTE: Int + + """dismissed_recommendation_count field predicates""" + dismissedRecommendationCount: Int + dismissedRecommendationCountNEQ: Int + dismissedRecommendationCountIn: [Int!] + dismissedRecommendationCountNotIn: [Int!] + dismissedRecommendationCountGT: Int + dismissedRecommendationCountGTE: Int + dismissedRecommendationCountLT: Int + dismissedRecommendationCountLTE: Int """policy_pending_low_count field predicates""" policyPendingLowCount: Int @@ -5296,329 +5995,269 @@ input ServiceStatusCacheWhereInput { policyPendingCriticalCountLT: Int policyPendingCriticalCountLTE: Int - """service_volume_per_hour field predicates""" - serviceVolumePerHour: Float - serviceVolumePerHourNEQ: Float - serviceVolumePerHourIn: [Float!] - serviceVolumePerHourNotIn: [Float!] - serviceVolumePerHourGT: Float - serviceVolumePerHourGTE: Float - serviceVolumePerHourLT: Float - serviceVolumePerHourLTE: Float - serviceVolumePerHourIsNil: Boolean - serviceVolumePerHourNotNil: Boolean - - """service_debug_volume_per_hour field predicates""" - serviceDebugVolumePerHour: Float - serviceDebugVolumePerHourNEQ: Float - serviceDebugVolumePerHourIn: [Float!] - serviceDebugVolumePerHourNotIn: [Float!] - serviceDebugVolumePerHourGT: Float - serviceDebugVolumePerHourGTE: Float - serviceDebugVolumePerHourLT: Float - serviceDebugVolumePerHourLTE: Float - serviceDebugVolumePerHourIsNil: Boolean - serviceDebugVolumePerHourNotNil: Boolean - - """service_info_volume_per_hour field predicates""" - serviceInfoVolumePerHour: Float - serviceInfoVolumePerHourNEQ: Float - serviceInfoVolumePerHourIn: [Float!] - serviceInfoVolumePerHourNotIn: [Float!] - serviceInfoVolumePerHourGT: Float - serviceInfoVolumePerHourGTE: Float - serviceInfoVolumePerHourLT: Float - serviceInfoVolumePerHourLTE: Float - serviceInfoVolumePerHourIsNil: Boolean - serviceInfoVolumePerHourNotNil: Boolean - - """service_warn_volume_per_hour field predicates""" - serviceWarnVolumePerHour: Float - serviceWarnVolumePerHourNEQ: Float - serviceWarnVolumePerHourIn: [Float!] - serviceWarnVolumePerHourNotIn: [Float!] - serviceWarnVolumePerHourGT: Float - serviceWarnVolumePerHourGTE: Float - serviceWarnVolumePerHourLT: Float - serviceWarnVolumePerHourLTE: Float - serviceWarnVolumePerHourIsNil: Boolean - serviceWarnVolumePerHourNotNil: Boolean - - """service_error_volume_per_hour field predicates""" - serviceErrorVolumePerHour: Float - serviceErrorVolumePerHourNEQ: Float - serviceErrorVolumePerHourIn: [Float!] - serviceErrorVolumePerHourNotIn: [Float!] - serviceErrorVolumePerHourGT: Float - serviceErrorVolumePerHourGTE: Float - serviceErrorVolumePerHourLT: Float - serviceErrorVolumePerHourLTE: Float - serviceErrorVolumePerHourIsNil: Boolean - serviceErrorVolumePerHourNotNil: Boolean - - """service_other_volume_per_hour field predicates""" - serviceOtherVolumePerHour: Float - serviceOtherVolumePerHourNEQ: Float - serviceOtherVolumePerHourIn: [Float!] - serviceOtherVolumePerHourNotIn: [Float!] - serviceOtherVolumePerHourGT: Float - serviceOtherVolumePerHourGTE: Float - serviceOtherVolumePerHourLT: Float - serviceOtherVolumePerHourLTE: Float - serviceOtherVolumePerHourIsNil: Boolean - serviceOtherVolumePerHourNotNil: Boolean - - """service_cost_per_hour_volume_usd field predicates""" - serviceCostPerHourVolumeUsd: Float - serviceCostPerHourVolumeUsdNEQ: Float - serviceCostPerHourVolumeUsdIn: [Float!] - serviceCostPerHourVolumeUsdNotIn: [Float!] - serviceCostPerHourVolumeUsdGT: Float - serviceCostPerHourVolumeUsdGTE: Float - serviceCostPerHourVolumeUsdLT: Float - serviceCostPerHourVolumeUsdLTE: Float - serviceCostPerHourVolumeUsdIsNil: Boolean - serviceCostPerHourVolumeUsdNotNil: Boolean - - """log_event_volume_per_hour field predicates""" - logEventVolumePerHour: Float - logEventVolumePerHourNEQ: Float - logEventVolumePerHourIn: [Float!] - logEventVolumePerHourNotIn: [Float!] - logEventVolumePerHourGT: Float - logEventVolumePerHourGTE: Float - logEventVolumePerHourLT: Float - logEventVolumePerHourLTE: Float - logEventVolumePerHourIsNil: Boolean - logEventVolumePerHourNotNil: Boolean - - """log_event_bytes_per_hour field predicates""" - logEventBytesPerHour: Float - logEventBytesPerHourNEQ: Float - logEventBytesPerHourIn: [Float!] - logEventBytesPerHourNotIn: [Float!] - logEventBytesPerHourGT: Float - logEventBytesPerHourGTE: Float - logEventBytesPerHourLT: Float - logEventBytesPerHourLTE: Float - logEventBytesPerHourIsNil: Boolean - logEventBytesPerHourNotNil: Boolean - - """log_event_cost_per_hour_bytes_usd field predicates""" - logEventCostPerHourBytesUsd: Float - logEventCostPerHourBytesUsdNEQ: Float - logEventCostPerHourBytesUsdIn: [Float!] - logEventCostPerHourBytesUsdNotIn: [Float!] - logEventCostPerHourBytesUsdGT: Float - logEventCostPerHourBytesUsdGTE: Float - logEventCostPerHourBytesUsdLT: Float - logEventCostPerHourBytesUsdLTE: Float - logEventCostPerHourBytesUsdIsNil: Boolean - logEventCostPerHourBytesUsdNotNil: Boolean - - """log_event_cost_per_hour_volume_usd field predicates""" - logEventCostPerHourVolumeUsd: Float - logEventCostPerHourVolumeUsdNEQ: Float - logEventCostPerHourVolumeUsdIn: [Float!] - logEventCostPerHourVolumeUsdNotIn: [Float!] - logEventCostPerHourVolumeUsdGT: Float - logEventCostPerHourVolumeUsdGTE: Float - logEventCostPerHourVolumeUsdLT: Float - logEventCostPerHourVolumeUsdLTE: Float - logEventCostPerHourVolumeUsdIsNil: Boolean - logEventCostPerHourVolumeUsdNotNil: Boolean - - """log_event_cost_per_hour_usd field predicates""" - logEventCostPerHourUsd: Float - logEventCostPerHourUsdNEQ: Float - logEventCostPerHourUsdIn: [Float!] - logEventCostPerHourUsdNotIn: [Float!] - logEventCostPerHourUsdGT: Float - logEventCostPerHourUsdGTE: Float - logEventCostPerHourUsdLT: Float - logEventCostPerHourUsdLTE: Float - logEventCostPerHourUsdIsNil: Boolean - logEventCostPerHourUsdNotNil: Boolean - - """estimated_volume_reduction_per_hour field predicates""" - estimatedVolumeReductionPerHour: Float - estimatedVolumeReductionPerHourNEQ: Float - estimatedVolumeReductionPerHourIn: [Float!] - estimatedVolumeReductionPerHourNotIn: [Float!] - estimatedVolumeReductionPerHourGT: Float - estimatedVolumeReductionPerHourGTE: Float - estimatedVolumeReductionPerHourLT: Float - estimatedVolumeReductionPerHourLTE: Float - estimatedVolumeReductionPerHourIsNil: Boolean - estimatedVolumeReductionPerHourNotNil: Boolean - - """estimated_bytes_reduction_per_hour field predicates""" - estimatedBytesReductionPerHour: Float - estimatedBytesReductionPerHourNEQ: Float - estimatedBytesReductionPerHourIn: [Float!] - estimatedBytesReductionPerHourNotIn: [Float!] - estimatedBytesReductionPerHourGT: Float - estimatedBytesReductionPerHourGTE: Float - estimatedBytesReductionPerHourLT: Float - estimatedBytesReductionPerHourLTE: Float - estimatedBytesReductionPerHourIsNil: Boolean - estimatedBytesReductionPerHourNotNil: Boolean - - """estimated_cost_reduction_per_hour_bytes_usd field predicates""" - estimatedCostReductionPerHourBytesUsd: Float - estimatedCostReductionPerHourBytesUsdNEQ: Float - estimatedCostReductionPerHourBytesUsdIn: [Float!] - estimatedCostReductionPerHourBytesUsdNotIn: [Float!] - estimatedCostReductionPerHourBytesUsdGT: Float - estimatedCostReductionPerHourBytesUsdGTE: Float - estimatedCostReductionPerHourBytesUsdLT: Float - estimatedCostReductionPerHourBytesUsdLTE: Float - estimatedCostReductionPerHourBytesUsdIsNil: Boolean - estimatedCostReductionPerHourBytesUsdNotNil: Boolean - - """estimated_cost_reduction_per_hour_volume_usd field predicates""" - estimatedCostReductionPerHourVolumeUsd: Float - estimatedCostReductionPerHourVolumeUsdNEQ: Float - estimatedCostReductionPerHourVolumeUsdIn: [Float!] - estimatedCostReductionPerHourVolumeUsdNotIn: [Float!] - estimatedCostReductionPerHourVolumeUsdGT: Float - estimatedCostReductionPerHourVolumeUsdGTE: Float - estimatedCostReductionPerHourVolumeUsdLT: Float - estimatedCostReductionPerHourVolumeUsdLTE: Float - estimatedCostReductionPerHourVolumeUsdIsNil: Boolean - estimatedCostReductionPerHourVolumeUsdNotNil: Boolean - - """estimated_cost_reduction_per_hour_usd field predicates""" - estimatedCostReductionPerHourUsd: Float - estimatedCostReductionPerHourUsdNEQ: Float - estimatedCostReductionPerHourUsdIn: [Float!] - estimatedCostReductionPerHourUsdNotIn: [Float!] - estimatedCostReductionPerHourUsdGT: Float - estimatedCostReductionPerHourUsdGTE: Float - estimatedCostReductionPerHourUsdLT: Float - estimatedCostReductionPerHourUsdLTE: Float - estimatedCostReductionPerHourUsdIsNil: Boolean - estimatedCostReductionPerHourUsdNotNil: Boolean - - """observed_volume_per_hour_before field predicates""" - observedVolumePerHourBefore: Float - observedVolumePerHourBeforeNEQ: Float - observedVolumePerHourBeforeIn: [Float!] - observedVolumePerHourBeforeNotIn: [Float!] - observedVolumePerHourBeforeGT: Float - observedVolumePerHourBeforeGTE: Float - observedVolumePerHourBeforeLT: Float - observedVolumePerHourBeforeLTE: Float - observedVolumePerHourBeforeIsNil: Boolean - observedVolumePerHourBeforeNotNil: Boolean - - """observed_volume_per_hour_after field predicates""" - observedVolumePerHourAfter: Float - observedVolumePerHourAfterNEQ: Float - observedVolumePerHourAfterIn: [Float!] - observedVolumePerHourAfterNotIn: [Float!] - observedVolumePerHourAfterGT: Float - observedVolumePerHourAfterGTE: Float - observedVolumePerHourAfterLT: Float - observedVolumePerHourAfterLTE: Float - observedVolumePerHourAfterIsNil: Boolean - observedVolumePerHourAfterNotNil: Boolean - - """observed_bytes_per_hour_before field predicates""" - observedBytesPerHourBefore: Float - observedBytesPerHourBeforeNEQ: Float - observedBytesPerHourBeforeIn: [Float!] - observedBytesPerHourBeforeNotIn: [Float!] - observedBytesPerHourBeforeGT: Float - observedBytesPerHourBeforeGTE: Float - observedBytesPerHourBeforeLT: Float - observedBytesPerHourBeforeLTE: Float - observedBytesPerHourBeforeIsNil: Boolean - observedBytesPerHourBeforeNotNil: Boolean - - """observed_bytes_per_hour_after field predicates""" - observedBytesPerHourAfter: Float - observedBytesPerHourAfterNEQ: Float - observedBytesPerHourAfterIn: [Float!] - observedBytesPerHourAfterNotIn: [Float!] - observedBytesPerHourAfterGT: Float - observedBytesPerHourAfterGTE: Float - observedBytesPerHourAfterLT: Float - observedBytesPerHourAfterLTE: Float - observedBytesPerHourAfterIsNil: Boolean - observedBytesPerHourAfterNotNil: Boolean - - """observed_cost_per_hour_before_bytes_usd field predicates""" - observedCostPerHourBeforeBytesUsd: Float - observedCostPerHourBeforeBytesUsdNEQ: Float - observedCostPerHourBeforeBytesUsdIn: [Float!] - observedCostPerHourBeforeBytesUsdNotIn: [Float!] - observedCostPerHourBeforeBytesUsdGT: Float - observedCostPerHourBeforeBytesUsdGTE: Float - observedCostPerHourBeforeBytesUsdLT: Float - observedCostPerHourBeforeBytesUsdLTE: Float - observedCostPerHourBeforeBytesUsdIsNil: Boolean - observedCostPerHourBeforeBytesUsdNotNil: Boolean - - """observed_cost_per_hour_before_volume_usd field predicates""" - observedCostPerHourBeforeVolumeUsd: Float - observedCostPerHourBeforeVolumeUsdNEQ: Float - observedCostPerHourBeforeVolumeUsdIn: [Float!] - observedCostPerHourBeforeVolumeUsdNotIn: [Float!] - observedCostPerHourBeforeVolumeUsdGT: Float - observedCostPerHourBeforeVolumeUsdGTE: Float - observedCostPerHourBeforeVolumeUsdLT: Float - observedCostPerHourBeforeVolumeUsdLTE: Float - observedCostPerHourBeforeVolumeUsdIsNil: Boolean - observedCostPerHourBeforeVolumeUsdNotNil: Boolean - - """observed_cost_per_hour_before_usd field predicates""" - observedCostPerHourBeforeUsd: Float - observedCostPerHourBeforeUsdNEQ: Float - observedCostPerHourBeforeUsdIn: [Float!] - observedCostPerHourBeforeUsdNotIn: [Float!] - observedCostPerHourBeforeUsdGT: Float - observedCostPerHourBeforeUsdGTE: Float - observedCostPerHourBeforeUsdLT: Float - observedCostPerHourBeforeUsdLTE: Float - observedCostPerHourBeforeUsdIsNil: Boolean - observedCostPerHourBeforeUsdNotNil: Boolean - - """observed_cost_per_hour_after_bytes_usd field predicates""" - observedCostPerHourAfterBytesUsd: Float - observedCostPerHourAfterBytesUsdNEQ: Float - observedCostPerHourAfterBytesUsdIn: [Float!] - observedCostPerHourAfterBytesUsdNotIn: [Float!] - observedCostPerHourAfterBytesUsdGT: Float - observedCostPerHourAfterBytesUsdGTE: Float - observedCostPerHourAfterBytesUsdLT: Float - observedCostPerHourAfterBytesUsdLTE: Float - observedCostPerHourAfterBytesUsdIsNil: Boolean - observedCostPerHourAfterBytesUsdNotNil: Boolean - - """observed_cost_per_hour_after_volume_usd field predicates""" - observedCostPerHourAfterVolumeUsd: Float - observedCostPerHourAfterVolumeUsdNEQ: Float - observedCostPerHourAfterVolumeUsdIn: [Float!] - observedCostPerHourAfterVolumeUsdNotIn: [Float!] - observedCostPerHourAfterVolumeUsdGT: Float - observedCostPerHourAfterVolumeUsdGTE: Float - observedCostPerHourAfterVolumeUsdLT: Float - observedCostPerHourAfterVolumeUsdLTE: Float - observedCostPerHourAfterVolumeUsdIsNil: Boolean - observedCostPerHourAfterVolumeUsdNotNil: Boolean - - """observed_cost_per_hour_after_usd field predicates""" - observedCostPerHourAfterUsd: Float - observedCostPerHourAfterUsdNEQ: Float - observedCostPerHourAfterUsdIn: [Float!] - observedCostPerHourAfterUsdNotIn: [Float!] - observedCostPerHourAfterUsdGT: Float - observedCostPerHourAfterUsdGTE: Float - observedCostPerHourAfterUsdLT: Float - observedCostPerHourAfterUsdLTE: Float - observedCostPerHourAfterUsdIsNil: Boolean - observedCostPerHourAfterUsdNotNil: Boolean + """current_service_events_per_hour field predicates""" + currentServiceEventsPerHour: Float + currentServiceEventsPerHourNEQ: Float + currentServiceEventsPerHourIn: [Float!] + currentServiceEventsPerHourNotIn: [Float!] + currentServiceEventsPerHourGT: Float + currentServiceEventsPerHourGTE: Float + currentServiceEventsPerHourLT: Float + currentServiceEventsPerHourLTE: Float + currentServiceEventsPerHourIsNil: Boolean + currentServiceEventsPerHourNotNil: Boolean + + """current_service_debug_events_per_hour field predicates""" + currentServiceDebugEventsPerHour: Float + currentServiceDebugEventsPerHourNEQ: Float + currentServiceDebugEventsPerHourIn: [Float!] + currentServiceDebugEventsPerHourNotIn: [Float!] + currentServiceDebugEventsPerHourGT: Float + currentServiceDebugEventsPerHourGTE: Float + currentServiceDebugEventsPerHourLT: Float + currentServiceDebugEventsPerHourLTE: Float + currentServiceDebugEventsPerHourIsNil: Boolean + currentServiceDebugEventsPerHourNotNil: Boolean + + """current_service_info_events_per_hour field predicates""" + currentServiceInfoEventsPerHour: Float + currentServiceInfoEventsPerHourNEQ: Float + currentServiceInfoEventsPerHourIn: [Float!] + currentServiceInfoEventsPerHourNotIn: [Float!] + currentServiceInfoEventsPerHourGT: Float + currentServiceInfoEventsPerHourGTE: Float + currentServiceInfoEventsPerHourLT: Float + currentServiceInfoEventsPerHourLTE: Float + currentServiceInfoEventsPerHourIsNil: Boolean + currentServiceInfoEventsPerHourNotNil: Boolean + + """current_service_warn_events_per_hour field predicates""" + currentServiceWarnEventsPerHour: Float + currentServiceWarnEventsPerHourNEQ: Float + currentServiceWarnEventsPerHourIn: [Float!] + currentServiceWarnEventsPerHourNotIn: [Float!] + currentServiceWarnEventsPerHourGT: Float + currentServiceWarnEventsPerHourGTE: Float + currentServiceWarnEventsPerHourLT: Float + currentServiceWarnEventsPerHourLTE: Float + currentServiceWarnEventsPerHourIsNil: Boolean + currentServiceWarnEventsPerHourNotNil: Boolean + + """current_service_error_events_per_hour field predicates""" + currentServiceErrorEventsPerHour: Float + currentServiceErrorEventsPerHourNEQ: Float + currentServiceErrorEventsPerHourIn: [Float!] + currentServiceErrorEventsPerHourNotIn: [Float!] + currentServiceErrorEventsPerHourGT: Float + currentServiceErrorEventsPerHourGTE: Float + currentServiceErrorEventsPerHourLT: Float + currentServiceErrorEventsPerHourLTE: Float + currentServiceErrorEventsPerHourIsNil: Boolean + currentServiceErrorEventsPerHourNotNil: Boolean + + """current_service_other_events_per_hour field predicates""" + currentServiceOtherEventsPerHour: Float + currentServiceOtherEventsPerHourNEQ: Float + currentServiceOtherEventsPerHourIn: [Float!] + currentServiceOtherEventsPerHourNotIn: [Float!] + currentServiceOtherEventsPerHourGT: Float + currentServiceOtherEventsPerHourGTE: Float + currentServiceOtherEventsPerHourLT: Float + currentServiceOtherEventsPerHourLTE: Float + currentServiceOtherEventsPerHourIsNil: Boolean + currentServiceOtherEventsPerHourNotNil: Boolean + + """current_service_volume_usd_per_hour field predicates""" + currentServiceVolumeUsdPerHour: Float + currentServiceVolumeUsdPerHourNEQ: Float + currentServiceVolumeUsdPerHourIn: [Float!] + currentServiceVolumeUsdPerHourNotIn: [Float!] + currentServiceVolumeUsdPerHourGT: Float + currentServiceVolumeUsdPerHourGTE: Float + currentServiceVolumeUsdPerHourLT: Float + currentServiceVolumeUsdPerHourLTE: Float + currentServiceVolumeUsdPerHourIsNil: Boolean + currentServiceVolumeUsdPerHourNotNil: Boolean + + """current_events_per_hour field predicates""" + currentEventsPerHour: Float + currentEventsPerHourNEQ: Float + currentEventsPerHourIn: [Float!] + currentEventsPerHourNotIn: [Float!] + currentEventsPerHourGT: Float + currentEventsPerHourGTE: Float + currentEventsPerHourLT: Float + currentEventsPerHourLTE: Float + currentEventsPerHourIsNil: Boolean + currentEventsPerHourNotNil: Boolean + + """current_bytes_per_hour field predicates""" + currentBytesPerHour: Float + currentBytesPerHourNEQ: Float + currentBytesPerHourIn: [Float!] + currentBytesPerHourNotIn: [Float!] + currentBytesPerHourGT: Float + currentBytesPerHourGTE: Float + currentBytesPerHourLT: Float + currentBytesPerHourLTE: Float + currentBytesPerHourIsNil: Boolean + currentBytesPerHourNotNil: Boolean + + """current_bytes_usd_per_hour field predicates""" + currentBytesUsdPerHour: Float + currentBytesUsdPerHourNEQ: Float + currentBytesUsdPerHourIn: [Float!] + currentBytesUsdPerHourNotIn: [Float!] + currentBytesUsdPerHourGT: Float + currentBytesUsdPerHourGTE: Float + currentBytesUsdPerHourLT: Float + currentBytesUsdPerHourLTE: Float + currentBytesUsdPerHourIsNil: Boolean + currentBytesUsdPerHourNotNil: Boolean + + """current_volume_usd_per_hour field predicates""" + currentVolumeUsdPerHour: Float + currentVolumeUsdPerHourNEQ: Float + currentVolumeUsdPerHourIn: [Float!] + currentVolumeUsdPerHourNotIn: [Float!] + currentVolumeUsdPerHourGT: Float + currentVolumeUsdPerHourGTE: Float + currentVolumeUsdPerHourLT: Float + currentVolumeUsdPerHourLTE: Float + currentVolumeUsdPerHourIsNil: Boolean + currentVolumeUsdPerHourNotNil: Boolean + + """current_total_usd_per_hour field predicates""" + currentTotalUsdPerHour: Float + currentTotalUsdPerHourNEQ: Float + currentTotalUsdPerHourIn: [Float!] + currentTotalUsdPerHourNotIn: [Float!] + currentTotalUsdPerHourGT: Float + currentTotalUsdPerHourGTE: Float + currentTotalUsdPerHourLT: Float + currentTotalUsdPerHourLTE: Float + currentTotalUsdPerHourIsNil: Boolean + currentTotalUsdPerHourNotNil: Boolean + + """estimated_events_per_hour field predicates""" + estimatedEventsPerHour: Float + estimatedEventsPerHourNEQ: Float + estimatedEventsPerHourIn: [Float!] + estimatedEventsPerHourNotIn: [Float!] + estimatedEventsPerHourGT: Float + estimatedEventsPerHourGTE: Float + estimatedEventsPerHourLT: Float + estimatedEventsPerHourLTE: Float + estimatedEventsPerHourIsNil: Boolean + estimatedEventsPerHourNotNil: Boolean + + """estimated_bytes_per_hour field predicates""" + estimatedBytesPerHour: Float + estimatedBytesPerHourNEQ: Float + estimatedBytesPerHourIn: [Float!] + estimatedBytesPerHourNotIn: [Float!] + estimatedBytesPerHourGT: Float + estimatedBytesPerHourGTE: Float + estimatedBytesPerHourLT: Float + estimatedBytesPerHourLTE: Float + estimatedBytesPerHourIsNil: Boolean + estimatedBytesPerHourNotNil: Boolean + + """estimated_bytes_usd_per_hour field predicates""" + estimatedBytesUsdPerHour: Float + estimatedBytesUsdPerHourNEQ: Float + estimatedBytesUsdPerHourIn: [Float!] + estimatedBytesUsdPerHourNotIn: [Float!] + estimatedBytesUsdPerHourGT: Float + estimatedBytesUsdPerHourGTE: Float + estimatedBytesUsdPerHourLT: Float + estimatedBytesUsdPerHourLTE: Float + estimatedBytesUsdPerHourIsNil: Boolean + estimatedBytesUsdPerHourNotNil: Boolean + + """estimated_volume_usd_per_hour field predicates""" + estimatedVolumeUsdPerHour: Float + estimatedVolumeUsdPerHourNEQ: Float + estimatedVolumeUsdPerHourIn: [Float!] + estimatedVolumeUsdPerHourNotIn: [Float!] + estimatedVolumeUsdPerHourGT: Float + estimatedVolumeUsdPerHourGTE: Float + estimatedVolumeUsdPerHourLT: Float + estimatedVolumeUsdPerHourLTE: Float + estimatedVolumeUsdPerHourIsNil: Boolean + estimatedVolumeUsdPerHourNotNil: Boolean + + """estimated_total_usd_per_hour field predicates""" + estimatedTotalUsdPerHour: Float + estimatedTotalUsdPerHourNEQ: Float + estimatedTotalUsdPerHourIn: [Float!] + estimatedTotalUsdPerHourNotIn: [Float!] + estimatedTotalUsdPerHourGT: Float + estimatedTotalUsdPerHourGTE: Float + estimatedTotalUsdPerHourLT: Float + estimatedTotalUsdPerHourLTE: Float + estimatedTotalUsdPerHourIsNil: Boolean + estimatedTotalUsdPerHourNotNil: Boolean + + """impact_events_per_hour field predicates""" + impactEventsPerHour: Float + impactEventsPerHourNEQ: Float + impactEventsPerHourIn: [Float!] + impactEventsPerHourNotIn: [Float!] + impactEventsPerHourGT: Float + impactEventsPerHourGTE: Float + impactEventsPerHourLT: Float + impactEventsPerHourLTE: Float + impactEventsPerHourIsNil: Boolean + impactEventsPerHourNotNil: Boolean + + """impact_bytes_per_hour field predicates""" + impactBytesPerHour: Float + impactBytesPerHourNEQ: Float + impactBytesPerHourIn: [Float!] + impactBytesPerHourNotIn: [Float!] + impactBytesPerHourGT: Float + impactBytesPerHourGTE: Float + impactBytesPerHourLT: Float + impactBytesPerHourLTE: Float + impactBytesPerHourIsNil: Boolean + impactBytesPerHourNotNil: Boolean + + """impact_bytes_usd_per_hour field predicates""" + impactBytesUsdPerHour: Float + impactBytesUsdPerHourNEQ: Float + impactBytesUsdPerHourIn: [Float!] + impactBytesUsdPerHourNotIn: [Float!] + impactBytesUsdPerHourGT: Float + impactBytesUsdPerHourGTE: Float + impactBytesUsdPerHourLT: Float + impactBytesUsdPerHourLTE: Float + impactBytesUsdPerHourIsNil: Boolean + impactBytesUsdPerHourNotNil: Boolean + + """impact_volume_usd_per_hour field predicates""" + impactVolumeUsdPerHour: Float + impactVolumeUsdPerHourNEQ: Float + impactVolumeUsdPerHourIn: [Float!] + impactVolumeUsdPerHourNotIn: [Float!] + impactVolumeUsdPerHourGT: Float + impactVolumeUsdPerHourGTE: Float + impactVolumeUsdPerHourLT: Float + impactVolumeUsdPerHourLTE: Float + impactVolumeUsdPerHourIsNil: Boolean + impactVolumeUsdPerHourNotNil: Boolean + + """impact_total_usd_per_hour field predicates""" + impactTotalUsdPerHour: Float + impactTotalUsdPerHourNEQ: Float + impactTotalUsdPerHourIn: [Float!] + impactTotalUsdPerHourNotIn: [Float!] + impactTotalUsdPerHourGT: Float + impactTotalUsdPerHourGTE: Float + impactTotalUsdPerHourLT: Float + impactTotalUsdPerHourLTE: Float + impactTotalUsdPerHourIsNil: Boolean + impactTotalUsdPerHourNotNil: Boolean """refreshed_at field predicates""" refreshedAt: Time @@ -6456,8 +7095,8 @@ type Workspace implements Node { """Chat conversations in this workspace""" conversations: [Conversation!] - """Log event policies for this workspace""" - logEventPolicies: [LogEventPolicy!] + """Log event recommendations for this workspace""" + logEventRecommendations: [LogEventRecommendation!] } """A connection to a list of items.""" @@ -6583,8 +7222,8 @@ input WorkspaceWhereInput { hasConversations: Boolean hasConversationsWith: [ConversationWhereInput!] - """log_event_policies edge predicates""" - hasLogEventPolicies: Boolean - hasLogEventPoliciesWith: [LogEventPolicyWhereInput!] + """log_event_recommendations edge predicates""" + hasLogEventRecommendations: Boolean + hasLogEventRecommendationsWith: [LogEventRecommendationWhereInput!] } diff --git a/internal/boundary/graphql/policy_service.go b/internal/boundary/graphql/policy_service.go index edc67220..cfda7269 100644 --- a/internal/boundary/graphql/policy_service.go +++ b/internal/boundary/graphql/policy_service.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/usetero/cli/internal/boundary/graphql/gen" "github.com/usetero/cli/internal/log" ) @@ -34,7 +35,7 @@ func NewPolicyService(client Client, scope log.Scope) *PolicyService { func (s *PolicyService) ApprovePolicy(ctx context.Context, id string) error { s.scope.Debug("approving policy via API", "id", id) - _, err := s.client.ApproveLogEventPolicy(ctx, id) + _, err := s.client.ApproveLogEventRecommendation(ctx, id, gen.EnforcementTargetInput{}) if err != nil { s.scope.Error("failed to approve policy", "error", err, "id", id) if classified := classifyError(err); classified != nil { @@ -51,7 +52,7 @@ func (s *PolicyService) ApprovePolicy(ctx context.Context, id string) error { func (s *PolicyService) DismissPolicy(ctx context.Context, id string) error { s.scope.Debug("dismissing policy via API", "id", id) - _, err := s.client.DismissLogEventPolicy(ctx, id) + _, err := s.client.DismissLogEventRecommendation(ctx, id) if err != nil { s.scope.Error("failed to dismiss policy", "error", err, "id", id) if classified := classifyError(err); classified != nil { diff --git a/internal/cmd/debug.go b/internal/cmd/debug.go index 8448f2c2..50084fc3 100644 --- a/internal/cmd/debug.go +++ b/internal/cmd/debug.go @@ -60,6 +60,8 @@ func newDebugStatusCmd(scope log.Scope, cliConfig *config.CLIConfig) *cobra.Comm if err != nil { return err } + // Datadog status queries require account scoping via X-Account-ID. + services = services.WithAccountID(accountID) // Get the datadog account for this account ddAccount, err := services.DatadogAccounts.GetAccount(cmd.Context(), accountID) diff --git a/internal/core/bootstrap/messages.go b/internal/core/bootstrap/messages.go index 4248666f..d0ddd399 100644 --- a/internal/core/bootstrap/messages.go +++ b/internal/core/bootstrap/messages.go @@ -86,6 +86,7 @@ type OnboardingComplete struct { type PreflightState struct { Outcome PreflightOutcome HasValidAuth bool + User *auth.User Role string ActiveOrgID domain.OrganizationID DefaultAccountID domain.AccountID diff --git a/internal/core/bootstrap/state.go b/internal/core/bootstrap/state.go index f81e1422..4399cc5e 100644 --- a/internal/core/bootstrap/state.go +++ b/internal/core/bootstrap/state.go @@ -32,6 +32,9 @@ func ApplyPreflight(state State, resolved PreflightState) (State, Gate) { if resolved.Account != nil { state.Account = resolved.Account } + if resolved.User != nil { + state.User = resolved.User + } return state, next } diff --git a/internal/core/bootstrap/state_test.go b/internal/core/bootstrap/state_test.go index 760c67d1..7b920593 100644 --- a/internal/core/bootstrap/state_test.go +++ b/internal/core/bootstrap/state_test.go @@ -3,18 +3,21 @@ package bootstrap import ( "testing" + "github.com/usetero/cli/internal/auth" "github.com/usetero/cli/internal/domain" ) func TestApplyPreflight(t *testing.T) { t.Parallel() + user := &auth.User{ID: "user-1"} org := &domain.Organization{ID: "org-1", Name: "Org 1"} account := &domain.Account{ID: "acc-1", Name: "Acc 1"} state, next := ApplyPreflight(State{}, PreflightState{ Outcome: PreflightOutcomeResolved, HasValidAuth: true, + User: user, Role: RolePlatform, Org: org, Account: account, @@ -29,4 +32,7 @@ func TestApplyPreflight(t *testing.T) { if state.Account == nil || state.Account.ID != account.ID { t.Fatalf("account not applied: %#v", state.Account) } + if state.User == nil || state.User.ID != user.ID { + t.Fatalf("user not applied: %#v", state.User) + } } diff --git a/internal/powersync/extension/schema.json b/internal/powersync/extension/schema.json index cabe3801..c6387b8e 100644 --- a/internal/powersync/extension/schema.json +++ b/internal/powersync/extension/schema.json @@ -1 +1 @@ -{"tables":[{"name":"conversation_contexts","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"added_by","type":"text"},{"name":"conversation_id","type":"text"},{"name":"created_at","type":"text"},{"name":"entity_id","type":"text"},{"name":"entity_type","type":"text"}],"indexes":[]},{"name":"conversations","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"created_at","type":"text"},{"name":"title","type":"text"},{"name":"user_id","type":"text"},{"name":"view_id","type":"text"},{"name":"workspace_id","type":"text"}],"indexes":[{"name":"account_id","columns":[{"name":"account_id","ascending":true,"type":"text"}]}]},{"name":"datadog_account_statuses_cache","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"datadog_account_id","type":"text"},{"name":"disabled_services","type":"integer"},{"name":"estimated_bytes_reduction_per_hour","type":"real"},{"name":"estimated_cost_reduction_per_hour_bytes_usd","type":"real"},{"name":"estimated_cost_reduction_per_hour_usd","type":"real"},{"name":"estimated_cost_reduction_per_hour_volume_usd","type":"real"},{"name":"estimated_volume_reduction_per_hour","type":"real"},{"name":"health","type":"text"},{"name":"inactive_services","type":"integer"},{"name":"log_active_services","type":"integer"},{"name":"log_event_analyzed_count","type":"integer"},{"name":"log_event_bytes_per_hour","type":"real"},{"name":"log_event_cost_per_hour_bytes_usd","type":"real"},{"name":"log_event_cost_per_hour_usd","type":"real"},{"name":"log_event_cost_per_hour_volume_usd","type":"real"},{"name":"log_event_count","type":"integer"},{"name":"log_event_volume_per_hour","type":"real"},{"name":"log_service_count","type":"integer"},{"name":"observed_bytes_per_hour_after","type":"real"},{"name":"observed_bytes_per_hour_before","type":"real"},{"name":"observed_cost_per_hour_after_bytes_usd","type":"real"},{"name":"observed_cost_per_hour_after_usd","type":"real"},{"name":"observed_cost_per_hour_after_volume_usd","type":"real"},{"name":"observed_cost_per_hour_before_bytes_usd","type":"real"},{"name":"observed_cost_per_hour_before_usd","type":"real"},{"name":"observed_cost_per_hour_before_volume_usd","type":"real"},{"name":"observed_volume_per_hour_after","type":"real"},{"name":"observed_volume_per_hour_before","type":"real"},{"name":"ok_services","type":"integer"},{"name":"policy_approved_count","type":"integer"},{"name":"policy_dismissed_count","type":"integer"},{"name":"policy_pending_count","type":"integer"},{"name":"policy_pending_critical_count","type":"integer"},{"name":"policy_pending_high_count","type":"integer"},{"name":"policy_pending_low_count","type":"integer"},{"name":"policy_pending_medium_count","type":"integer"},{"name":"ready_for_use","type":"integer"},{"name":"service_cost_per_hour_volume_usd","type":"real"},{"name":"service_volume_per_hour","type":"real"}],"indexes":[{"name":"datadog_account_id","columns":[{"name":"datadog_account_id","ascending":true,"type":"text"}]}]},{"name":"datadog_accounts","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"cost_per_gb_ingested","type":"real"},{"name":"created_at","type":"text"},{"name":"name","type":"text"},{"name":"site","type":"text"}],"indexes":[]},{"name":"datadog_log_indexes","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"cost_per_million_events_indexed","type":"real"},{"name":"created_at","type":"text"},{"name":"datadog_account_id","type":"text"},{"name":"name","type":"text"}],"indexes":[]},{"name":"log_event_fields","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"baseline_avg_bytes","type":"real"},{"name":"created_at","type":"text"},{"name":"field_path","type":"text"},{"name":"log_event_id","type":"text"},{"name":"value_distribution","type":"text"}],"indexes":[]},{"name":"log_event_policies","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"action","type":"text"},{"name":"analysis","type":"text"},{"name":"approved_at","type":"text"},{"name":"approved_baseline_avg_bytes","type":"real"},{"name":"approved_baseline_volume_per_hour","type":"real"},{"name":"approved_by","type":"text"},{"name":"category","type":"text"},{"name":"category_type","type":"text"},{"name":"created_at","type":"text"},{"name":"dismissed_at","type":"text"},{"name":"dismissed_by","type":"text"},{"name":"log_event_id","type":"text"},{"name":"severity","type":"text"},{"name":"subjective","type":"integer"},{"name":"workspace_id","type":"text"}],"indexes":[{"name":"log_event_id","columns":[{"name":"log_event_id","ascending":true,"type":"text"}]}]},{"name":"log_event_policy_category_statuses_cache","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"action","type":"text"},{"name":"approved_count","type":"integer"},{"name":"boundary","type":"text"},{"name":"category","type":"text"},{"name":"category_type","type":"text"},{"name":"dismissed_count","type":"integer"},{"name":"display_name","type":"text"},{"name":"estimated_bytes_reduction_per_hour","type":"real"},{"name":"estimated_cost_reduction_per_hour_bytes_usd","type":"real"},{"name":"estimated_cost_reduction_per_hour_usd","type":"real"},{"name":"estimated_cost_reduction_per_hour_volume_usd","type":"real"},{"name":"estimated_volume_reduction_per_hour","type":"real"},{"name":"events_with_volumes","type":"integer"},{"name":"pending_count","type":"integer"},{"name":"policy_pending_critical_count","type":"integer"},{"name":"policy_pending_high_count","type":"integer"},{"name":"policy_pending_low_count","type":"integer"},{"name":"policy_pending_medium_count","type":"integer"},{"name":"principle","type":"text"},{"name":"subjective","type":"integer"},{"name":"total_event_count","type":"integer"}],"indexes":[]},{"name":"log_event_policy_statuses_cache","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"action","type":"text"},{"name":"approved_at","type":"text"},{"name":"bytes_per_hour","type":"real"},{"name":"category","type":"text"},{"name":"category_type","type":"text"},{"name":"created_at","type":"text"},{"name":"dismissed_at","type":"text"},{"name":"estimated_bytes_reduction_per_hour","type":"real"},{"name":"estimated_cost_reduction_per_hour_bytes_usd","type":"real"},{"name":"estimated_cost_reduction_per_hour_usd","type":"real"},{"name":"estimated_cost_reduction_per_hour_volume_usd","type":"real"},{"name":"estimated_volume_reduction_per_hour","type":"real"},{"name":"log_event_id","type":"text"},{"name":"log_event_name","type":"text"},{"name":"policy_id","type":"text"},{"name":"service_id","type":"text"},{"name":"service_name","type":"text"},{"name":"severity","type":"text"},{"name":"status","type":"text"},{"name":"subjective","type":"integer"},{"name":"survival_rate","type":"real"},{"name":"volume_per_hour","type":"real"},{"name":"workspace_id","type":"text"}],"indexes":[{"name":"log_event_id","columns":[{"name":"log_event_id","ascending":true,"type":"text"}]},{"name":"category_status","columns":[{"name":"category","ascending":true,"type":"text"},{"name":"status","ascending":true,"type":"text"}]}]},{"name":"log_event_statuses_cache","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"approved_policy_count","type":"integer"},{"name":"bytes_per_hour","type":"real"},{"name":"cost_per_hour_bytes_usd","type":"real"},{"name":"cost_per_hour_usd","type":"real"},{"name":"cost_per_hour_volume_usd","type":"real"},{"name":"dismissed_policy_count","type":"integer"},{"name":"estimated_bytes_reduction_per_hour","type":"real"},{"name":"estimated_cost_reduction_per_hour_bytes_usd","type":"real"},{"name":"estimated_cost_reduction_per_hour_usd","type":"real"},{"name":"estimated_cost_reduction_per_hour_volume_usd","type":"real"},{"name":"estimated_volume_reduction_per_hour","type":"real"},{"name":"has_been_analyzed","type":"integer"},{"name":"has_volumes","type":"integer"},{"name":"log_event_id","type":"text"},{"name":"observed_bytes_per_hour_after","type":"real"},{"name":"observed_bytes_per_hour_before","type":"real"},{"name":"observed_cost_per_hour_after_bytes_usd","type":"real"},{"name":"observed_cost_per_hour_after_usd","type":"real"},{"name":"observed_cost_per_hour_after_volume_usd","type":"real"},{"name":"observed_cost_per_hour_before_bytes_usd","type":"real"},{"name":"observed_cost_per_hour_before_usd","type":"real"},{"name":"observed_cost_per_hour_before_volume_usd","type":"real"},{"name":"observed_volume_per_hour_after","type":"real"},{"name":"observed_volume_per_hour_before","type":"real"},{"name":"pending_policy_count","type":"integer"},{"name":"policy_count","type":"integer"},{"name":"policy_pending_critical_count","type":"integer"},{"name":"policy_pending_high_count","type":"integer"},{"name":"policy_pending_low_count","type":"integer"},{"name":"policy_pending_medium_count","type":"integer"},{"name":"service_id","type":"text"},{"name":"volume_per_hour","type":"real"}],"indexes":[{"name":"log_event_id","columns":[{"name":"log_event_id","ascending":true,"type":"text"}]},{"name":"service_id","columns":[{"name":"service_id","ascending":true,"type":"text"}]}]},{"name":"log_events","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"baseline_avg_bytes","type":"real"},{"name":"baseline_volume_per_hour","type":"real"},{"name":"created_at","type":"text"},{"name":"description","type":"text"},{"name":"event_nature","type":"text"},{"name":"examples","type":"text"},{"name":"matchers","type":"text"},{"name":"name","type":"text"},{"name":"service_id","type":"text"},{"name":"severity","type":"text"},{"name":"signal_purpose","type":"text"}],"indexes":[{"name":"service_id","columns":[{"name":"service_id","ascending":true,"type":"text"}]}]},{"name":"messages","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"content","type":"text"},{"name":"conversation_id","type":"text"},{"name":"created_at","type":"text"},{"name":"model","type":"text"},{"name":"role","type":"text"},{"name":"stop_reason","type":"text"}],"indexes":[{"name":"conversation_id","columns":[{"name":"conversation_id","ascending":true,"type":"text"}]}]},{"name":"service_statuses_cache","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"datadog_account_id","type":"text"},{"name":"estimated_bytes_reduction_per_hour","type":"real"},{"name":"estimated_cost_reduction_per_hour_bytes_usd","type":"real"},{"name":"estimated_cost_reduction_per_hour_usd","type":"real"},{"name":"estimated_cost_reduction_per_hour_volume_usd","type":"real"},{"name":"estimated_volume_reduction_per_hour","type":"real"},{"name":"health","type":"text"},{"name":"log_event_analyzed_count","type":"integer"},{"name":"log_event_bytes_per_hour","type":"real"},{"name":"log_event_cost_per_hour_bytes_usd","type":"real"},{"name":"log_event_cost_per_hour_usd","type":"real"},{"name":"log_event_cost_per_hour_volume_usd","type":"real"},{"name":"log_event_count","type":"integer"},{"name":"log_event_volume_per_hour","type":"real"},{"name":"observed_bytes_per_hour_after","type":"real"},{"name":"observed_bytes_per_hour_before","type":"real"},{"name":"observed_cost_per_hour_after_bytes_usd","type":"real"},{"name":"observed_cost_per_hour_after_usd","type":"real"},{"name":"observed_cost_per_hour_after_volume_usd","type":"real"},{"name":"observed_cost_per_hour_before_bytes_usd","type":"real"},{"name":"observed_cost_per_hour_before_usd","type":"real"},{"name":"observed_cost_per_hour_before_volume_usd","type":"real"},{"name":"observed_volume_per_hour_after","type":"real"},{"name":"observed_volume_per_hour_before","type":"real"},{"name":"policy_approved_count","type":"integer"},{"name":"policy_dismissed_count","type":"integer"},{"name":"policy_pending_count","type":"integer"},{"name":"policy_pending_critical_count","type":"integer"},{"name":"policy_pending_high_count","type":"integer"},{"name":"policy_pending_low_count","type":"integer"},{"name":"policy_pending_medium_count","type":"integer"},{"name":"service_cost_per_hour_volume_usd","type":"real"},{"name":"service_debug_volume_per_hour","type":"real"},{"name":"service_error_volume_per_hour","type":"real"},{"name":"service_id","type":"text"},{"name":"service_info_volume_per_hour","type":"real"},{"name":"service_other_volume_per_hour","type":"real"},{"name":"service_volume_per_hour","type":"real"},{"name":"service_warn_volume_per_hour","type":"real"}],"indexes":[{"name":"service_id","columns":[{"name":"service_id","ascending":true,"type":"text"}]}]},{"name":"services","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"created_at","type":"text"},{"name":"description","type":"text"},{"name":"enabled","type":"integer"},{"name":"initial_weekly_log_count","type":"integer"},{"name":"name","type":"text"}],"indexes":[{"name":"name","columns":[{"name":"name","ascending":true,"type":"text"}]}]},{"name":"teams","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"created_at","type":"text"},{"name":"name","type":"text"},{"name":"workspace_id","type":"text"}],"indexes":[]},{"name":"view_favorites","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"created_at","type":"text"},{"name":"user_id","type":"text"},{"name":"view_id","type":"text"}],"indexes":[]},{"name":"views","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"conversation_id","type":"text"},{"name":"created_at","type":"text"},{"name":"created_by","type":"text"},{"name":"entity_type","type":"text"},{"name":"forked_from_id","type":"text"},{"name":"message_id","type":"text"},{"name":"query","type":"text"}],"indexes":[]},{"name":"workspaces","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"created_at","type":"text"},{"name":"name","type":"text"},{"name":"purpose","type":"text"}],"indexes":[]}]} \ No newline at end of file +{"tables":[{"name":"conversation_contexts","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"added_by","type":"text"},{"name":"conversation_id","type":"text"},{"name":"created_at","type":"text"},{"name":"entity_id","type":"text"},{"name":"entity_type","type":"text"}],"indexes":[]},{"name":"conversations","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"created_at","type":"text"},{"name":"title","type":"text"},{"name":"user_id","type":"text"},{"name":"view_id","type":"text"},{"name":"workspace_id","type":"text"}],"indexes":[{"name":"account_id","columns":[{"name":"account_id","ascending":true,"type":"text"}]}]},{"name":"datadog_account_statuses_cache","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"approved_recommendation_count","type":"integer"},{"name":"current_bytes_per_hour","type":"real"},{"name":"current_bytes_usd_per_hour","type":"real"},{"name":"current_events_per_hour","type":"real"},{"name":"current_service_events_per_hour","type":"real"},{"name":"current_service_volume_usd_per_hour","type":"real"},{"name":"current_total_usd_per_hour","type":"real"},{"name":"current_volume_usd_per_hour","type":"real"},{"name":"datadog_account_id","type":"text"},{"name":"disabled_services","type":"integer"},{"name":"dismissed_recommendation_count","type":"integer"},{"name":"estimated_bytes_per_hour","type":"real"},{"name":"estimated_bytes_usd_per_hour","type":"real"},{"name":"estimated_events_per_hour","type":"real"},{"name":"estimated_total_usd_per_hour","type":"real"},{"name":"estimated_volume_usd_per_hour","type":"real"},{"name":"health","type":"text"},{"name":"impact_bytes_per_hour","type":"real"},{"name":"impact_bytes_usd_per_hour","type":"real"},{"name":"impact_events_per_hour","type":"real"},{"name":"impact_total_usd_per_hour","type":"real"},{"name":"impact_volume_usd_per_hour","type":"real"},{"name":"inactive_services","type":"integer"},{"name":"log_active_services","type":"integer"},{"name":"log_event_analyzed_count","type":"integer"},{"name":"log_event_count","type":"integer"},{"name":"log_service_count","type":"integer"},{"name":"ok_services","type":"integer"},{"name":"pending_recommendation_count","type":"integer"},{"name":"policy_pending_critical_count","type":"integer"},{"name":"policy_pending_high_count","type":"integer"},{"name":"policy_pending_low_count","type":"integer"},{"name":"policy_pending_medium_count","type":"integer"},{"name":"ready_for_use","type":"integer"},{"name":"recommendation_count","type":"integer"}],"indexes":[{"name":"datadog_account_id","columns":[{"name":"datadog_account_id","ascending":true,"type":"text"}]}]},{"name":"datadog_accounts","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"cost_per_gb_ingested","type":"real"},{"name":"created_at","type":"text"},{"name":"name","type":"text"},{"name":"site","type":"text"}],"indexes":[]},{"name":"datadog_log_indexes","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"cost_per_million_events_indexed","type":"real"},{"name":"created_at","type":"text"},{"name":"datadog_account_id","type":"text"},{"name":"name","type":"text"}],"indexes":[]},{"name":"log_event_recommendations","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"action","type":"text"},{"name":"analysis","type":"text"},{"name":"approved_at","type":"text"},{"name":"approved_baseline_avg_bytes","type":"real"},{"name":"approved_baseline_volume_per_hour","type":"real"},{"name":"approved_by","type":"text"},{"name":"category","type":"text"},{"name":"category_type","type":"text"},{"name":"created_at","type":"text"},{"name":"dismissed_at","type":"text"},{"name":"dismissed_by","type":"text"},{"name":"log_event_id","type":"text"},{"name":"severity","type":"text"},{"name":"subjective","type":"integer"},{"name":"workspace_id","type":"text"}],"indexes":[]},{"name":"log_event_statuses_cache","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"approved_recommendation_count","type":"integer"},{"name":"current_bytes_per_hour","type":"real"},{"name":"current_bytes_usd_per_hour","type":"real"},{"name":"current_events_per_hour","type":"real"},{"name":"current_total_usd_per_hour","type":"real"},{"name":"current_volume_usd_per_hour","type":"real"},{"name":"dismissed_recommendation_count","type":"integer"},{"name":"effective_policy_enabled","type":"integer"},{"name":"estimated_bytes_per_hour","type":"real"},{"name":"estimated_bytes_usd_per_hour","type":"real"},{"name":"estimated_events_per_hour","type":"real"},{"name":"estimated_total_usd_per_hour","type":"real"},{"name":"estimated_volume_usd_per_hour","type":"real"},{"name":"has_been_analyzed","type":"integer"},{"name":"has_volumes","type":"integer"},{"name":"impact_bytes_per_hour","type":"real"},{"name":"impact_bytes_usd_per_hour","type":"real"},{"name":"impact_events_per_hour","type":"real"},{"name":"impact_total_usd_per_hour","type":"real"},{"name":"impact_volume_usd_per_hour","type":"real"},{"name":"log_event_id","type":"text"},{"name":"pending_recommendation_count","type":"integer"},{"name":"policy_pending_critical_count","type":"integer"},{"name":"policy_pending_high_count","type":"integer"},{"name":"policy_pending_low_count","type":"integer"},{"name":"policy_pending_medium_count","type":"integer"},{"name":"recommendation_count","type":"integer"},{"name":"service_id","type":"text"}],"indexes":[{"name":"log_event_id","columns":[{"name":"log_event_id","ascending":true,"type":"text"}]},{"name":"service_id","columns":[{"name":"service_id","ascending":true,"type":"text"}]}]},{"name":"log_events","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"baseline_avg_bytes","type":"real"},{"name":"baseline_volume_per_hour","type":"real"},{"name":"created_at","type":"text"},{"name":"description","type":"text"},{"name":"event_nature","type":"text"},{"name":"examples","type":"text"},{"name":"matchers","type":"text"},{"name":"name","type":"text"},{"name":"service_id","type":"text"},{"name":"severity","type":"text"},{"name":"signal_purpose","type":"text"}],"indexes":[{"name":"service_id","columns":[{"name":"service_id","ascending":true,"type":"text"}]}]},{"name":"messages","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"content","type":"text"},{"name":"conversation_id","type":"text"},{"name":"created_at","type":"text"},{"name":"model","type":"text"},{"name":"role","type":"text"},{"name":"stop_reason","type":"text"}],"indexes":[{"name":"conversation_id","columns":[{"name":"conversation_id","ascending":true,"type":"text"}]}]},{"name":"recommendation_category_statuses_cache","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"action","type":"text"},{"name":"approved_count","type":"integer"},{"name":"boundary","type":"text"},{"name":"category","type":"text"},{"name":"category_type","type":"text"},{"name":"dismissed_count","type":"integer"},{"name":"display_name","type":"text"},{"name":"estimated_bytes_reduction_per_hour","type":"real"},{"name":"estimated_cost_reduction_per_hour_bytes_usd","type":"real"},{"name":"estimated_cost_reduction_per_hour_usd","type":"real"},{"name":"estimated_cost_reduction_per_hour_volume_usd","type":"real"},{"name":"estimated_volume_reduction_per_hour","type":"real"},{"name":"events_with_volumes","type":"integer"},{"name":"pending_count","type":"integer"},{"name":"policy_pending_critical_count","type":"integer"},{"name":"policy_pending_high_count","type":"integer"},{"name":"policy_pending_low_count","type":"integer"},{"name":"policy_pending_medium_count","type":"integer"},{"name":"principle","type":"text"},{"name":"subjective","type":"integer"},{"name":"total_event_count","type":"integer"}],"indexes":[]},{"name":"recommendation_statuses_cache","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"action","type":"text"},{"name":"approved_at","type":"text"},{"name":"category","type":"text"},{"name":"category_type","type":"text"},{"name":"created_at","type":"text"},{"name":"current_bytes_per_hour","type":"real"},{"name":"current_bytes_usd_per_hour","type":"real"},{"name":"current_events_per_hour","type":"real"},{"name":"current_total_usd_per_hour","type":"real"},{"name":"current_volume_usd_per_hour","type":"real"},{"name":"dismissed_at","type":"text"},{"name":"estimated_bytes_per_hour","type":"real"},{"name":"estimated_bytes_usd_per_hour","type":"real"},{"name":"estimated_events_per_hour","type":"real"},{"name":"estimated_total_usd_per_hour","type":"real"},{"name":"estimated_volume_usd_per_hour","type":"real"},{"name":"impact_bytes_per_hour","type":"real"},{"name":"impact_bytes_usd_per_hour","type":"real"},{"name":"impact_events_per_hour","type":"real"},{"name":"impact_total_usd_per_hour","type":"real"},{"name":"impact_volume_usd_per_hour","type":"real"},{"name":"log_event_id","type":"text"},{"name":"log_event_name","type":"text"},{"name":"recommendation_id","type":"text"},{"name":"service_id","type":"text"},{"name":"service_name","type":"text"},{"name":"severity","type":"text"},{"name":"status","type":"text"},{"name":"subjective","type":"integer"},{"name":"survival_rate","type":"real"},{"name":"workspace_id","type":"text"}],"indexes":[]},{"name":"service_statuses_cache","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"approved_recommendation_count","type":"integer"},{"name":"current_bytes_per_hour","type":"real"},{"name":"current_bytes_usd_per_hour","type":"real"},{"name":"current_events_per_hour","type":"real"},{"name":"current_service_debug_events_per_hour","type":"real"},{"name":"current_service_error_events_per_hour","type":"real"},{"name":"current_service_events_per_hour","type":"real"},{"name":"current_service_info_events_per_hour","type":"real"},{"name":"current_service_other_events_per_hour","type":"real"},{"name":"current_service_volume_usd_per_hour","type":"real"},{"name":"current_service_warn_events_per_hour","type":"real"},{"name":"current_total_usd_per_hour","type":"real"},{"name":"current_volume_usd_per_hour","type":"real"},{"name":"datadog_account_id","type":"text"},{"name":"dismissed_recommendation_count","type":"integer"},{"name":"estimated_bytes_per_hour","type":"real"},{"name":"estimated_bytes_usd_per_hour","type":"real"},{"name":"estimated_events_per_hour","type":"real"},{"name":"estimated_total_usd_per_hour","type":"real"},{"name":"estimated_volume_usd_per_hour","type":"real"},{"name":"health","type":"text"},{"name":"impact_bytes_per_hour","type":"real"},{"name":"impact_bytes_usd_per_hour","type":"real"},{"name":"impact_events_per_hour","type":"real"},{"name":"impact_total_usd_per_hour","type":"real"},{"name":"impact_volume_usd_per_hour","type":"real"},{"name":"log_event_analyzed_count","type":"integer"},{"name":"log_event_count","type":"integer"},{"name":"pending_recommendation_count","type":"integer"},{"name":"policy_pending_critical_count","type":"integer"},{"name":"policy_pending_high_count","type":"integer"},{"name":"policy_pending_low_count","type":"integer"},{"name":"policy_pending_medium_count","type":"integer"},{"name":"recommendation_count","type":"integer"},{"name":"service_id","type":"text"}],"indexes":[{"name":"service_id","columns":[{"name":"service_id","ascending":true,"type":"text"}]}]},{"name":"services","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"created_at","type":"text"},{"name":"description","type":"text"},{"name":"enabled","type":"integer"},{"name":"initial_weekly_log_count","type":"integer"},{"name":"name","type":"text"}],"indexes":[{"name":"name","columns":[{"name":"name","ascending":true,"type":"text"}]}]},{"name":"teams","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"created_at","type":"text"},{"name":"name","type":"text"},{"name":"workspace_id","type":"text"}],"indexes":[]},{"name":"view_favorites","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"created_at","type":"text"},{"name":"user_id","type":"text"},{"name":"view_id","type":"text"}],"indexes":[]},{"name":"views","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"conversation_id","type":"text"},{"name":"created_at","type":"text"},{"name":"created_by","type":"text"},{"name":"entity_type","type":"text"},{"name":"forked_from_id","type":"text"},{"name":"message_id","type":"text"},{"name":"query","type":"text"}],"indexes":[]},{"name":"workspaces","columns":[{"name":"id","type":"text"},{"name":"account_id","type":"text"},{"name":"created_at","type":"text"},{"name":"name","type":"text"},{"name":"purpose","type":"text"}],"indexes":[]}]} \ No newline at end of file diff --git a/internal/sqlite/gen/compliance_policies.sql.go b/internal/sqlite/gen/compliance_policies.sql.go index b326536c..0c959e5f 100644 --- a/internal/sqlite/gen/compliance_policies.sql.go +++ b/internal/sqlite/gen/compliance_policies.sql.go @@ -16,8 +16,8 @@ SELECT SELECT MAX(CASE json_extract(f.value, '$.observed') WHEN 1 THEN 1 ELSE 0 END) FROM json_each(json_extract(lep.analysis, '$.' || leps.category || '.fields')) f ), 0) = 1 THEN 1 ELSE 0 END) AS INTEGER) AS observed_count -FROM log_event_policy_statuses_cache leps -LEFT JOIN log_event_policies lep ON lep.id = leps.policy_id +FROM recommendation_statuses_cache leps +LEFT JOIN log_event_recommendations lep ON lep.id = leps.recommendation_id WHERE leps.category_type = 'compliance' AND leps.status = 'PENDING' GROUP BY leps.category ` @@ -57,18 +57,18 @@ SELECT COALESCE(s.name, '') AS service_name, COALESCE(le.name, '') AS log_event_name, COALESCE(lep.analysis, '') AS analysis, - les.volume_per_hour, + les.current_events_per_hour AS volume_per_hour, CAST(COALESCE(( SELECT MAX(CASE json_extract(f.value, '$.observed') WHEN 1 THEN 1 ELSE 0 END) FROM json_each(json_extract(lep.analysis, '$.' || ?1 || '.fields')) f ), 0) AS INTEGER) AS any_observed -FROM log_event_policy_statuses_cache leps +FROM recommendation_statuses_cache leps JOIN log_events le ON le.id = leps.log_event_id JOIN services s ON s.id = le.service_id -LEFT JOIN log_event_policies lep ON lep.id = leps.policy_id +LEFT JOIN log_event_recommendations lep ON lep.id = leps.recommendation_id LEFT JOIN log_event_statuses_cache les ON les.log_event_id = leps.log_event_id WHERE leps.category = ?1 AND leps.status = 'PENDING' -ORDER BY any_observed DESC, les.volume_per_hour DESC +ORDER BY any_observed DESC, les.current_events_per_hour DESC LIMIT ?2 ` diff --git a/internal/sqlite/gen/datadog_account_statuses.sql.go b/internal/sqlite/gen/datadog_account_statuses.sql.go index 36227698..189f7719 100644 --- a/internal/sqlite/gen/datadog_account_statuses.sql.go +++ b/internal/sqlite/gen/datadog_account_statuses.sql.go @@ -29,43 +29,43 @@ SELECT CAST(COALESCE(SUM(log_event_analyzed_count), 0) AS INTEGER) AS analyzed_count, -- policies - CAST(COALESCE(SUM(policy_pending_count), 0) AS INTEGER) AS pending_policy_count, - CAST(COALESCE(SUM(policy_approved_count), 0) AS INTEGER) AS approved_policy_count, - CAST(COALESCE(SUM(policy_dismissed_count), 0) AS INTEGER) AS dismissed_policy_count, + CAST(COALESCE(SUM(pending_recommendation_count), 0) AS INTEGER) AS pending_policy_count, + CAST(COALESCE(SUM(approved_recommendation_count), 0) AS INTEGER) AS approved_policy_count, + CAST(COALESCE(SUM(dismissed_recommendation_count), 0) AS INTEGER) AS dismissed_policy_count, CAST(COALESCE(SUM(policy_pending_critical_count), 0) AS INTEGER) AS policy_pending_critical_count, CAST(COALESCE(SUM(policy_pending_high_count), 0) AS INTEGER) AS policy_pending_high_count, CAST(COALESCE(SUM(policy_pending_medium_count), 0) AS INTEGER) AS policy_pending_medium_count, CAST(COALESCE(SUM(policy_pending_low_count), 0) AS INTEGER) AS policy_pending_low_count, -- estimated savings - SUM(estimated_cost_reduction_per_hour_usd) AS estimated_cost_per_hour, - SUM(estimated_cost_reduction_per_hour_bytes_usd) AS estimated_cost_per_hour_bytes, - SUM(estimated_cost_reduction_per_hour_volume_usd) AS estimated_cost_per_hour_volume, - SUM(estimated_volume_reduction_per_hour) AS estimated_volume_per_hour, - SUM(estimated_bytes_reduction_per_hour) AS estimated_bytes_per_hour, + SUM(impact_total_usd_per_hour) AS estimated_cost_per_hour, + SUM(impact_bytes_usd_per_hour) AS estimated_cost_per_hour_bytes, + SUM(impact_volume_usd_per_hour) AS estimated_cost_per_hour_volume, + SUM(impact_events_per_hour) AS estimated_volume_per_hour, + SUM(impact_bytes_per_hour) AS estimated_bytes_per_hour, -- observed impact - SUM(observed_cost_per_hour_before_usd) AS observed_cost_before, - SUM(observed_cost_per_hour_before_bytes_usd) AS observed_cost_before_bytes, - SUM(observed_cost_per_hour_before_volume_usd) AS observed_cost_before_volume, - SUM(observed_cost_per_hour_after_usd) AS observed_cost_after, - SUM(observed_cost_per_hour_after_bytes_usd) AS observed_cost_after_bytes, - SUM(observed_cost_per_hour_after_volume_usd) AS observed_cost_after_volume, - SUM(observed_volume_per_hour_before) AS observed_volume_before, - SUM(observed_volume_per_hour_after) AS observed_volume_after, - SUM(observed_bytes_per_hour_before) AS observed_bytes_before, - SUM(observed_bytes_per_hour_after) AS observed_bytes_after, + SUM(current_total_usd_per_hour) AS observed_cost_before, + SUM(current_bytes_usd_per_hour) AS observed_cost_before_bytes, + SUM(current_volume_usd_per_hour) AS observed_cost_before_volume, + SUM(current_total_usd_per_hour - impact_total_usd_per_hour) AS observed_cost_after, + SUM(current_bytes_usd_per_hour - impact_bytes_usd_per_hour) AS observed_cost_after_bytes, + SUM(current_volume_usd_per_hour - impact_volume_usd_per_hour) AS observed_cost_after_volume, + SUM(current_events_per_hour) AS observed_volume_before, + SUM(current_events_per_hour - impact_events_per_hour) AS observed_volume_after, + SUM(current_bytes_per_hour) AS observed_bytes_before, + SUM(current_bytes_per_hour - impact_bytes_per_hour) AS observed_bytes_after, -- totals - SUM(log_event_cost_per_hour_usd) AS total_cost_per_hour, - SUM(log_event_cost_per_hour_bytes_usd) AS total_cost_per_hour_bytes, - SUM(log_event_cost_per_hour_volume_usd) AS total_cost_per_hour_volume, - SUM(log_event_volume_per_hour) AS total_volume_per_hour, - SUM(log_event_bytes_per_hour) AS total_bytes_per_hour, + SUM(current_total_usd_per_hour) AS total_cost_per_hour, + SUM(current_bytes_usd_per_hour) AS total_cost_per_hour_bytes, + SUM(current_volume_usd_per_hour) AS total_cost_per_hour_volume, + SUM(current_events_per_hour) AS total_volume_per_hour, + SUM(current_bytes_per_hour) AS total_bytes_per_hour, -- service-level throughput - SUM(service_volume_per_hour) AS total_service_volume_per_hour, - SUM(service_cost_per_hour_volume_usd) AS total_service_cost_per_hour + SUM(current_service_events_per_hour) AS total_service_volume_per_hour, + SUM(current_service_volume_usd_per_hour) AS total_service_cost_per_hour FROM datadog_account_statuses_cache ` diff --git a/internal/sqlite/gen/log_event_policy_category_statuses.sql.go b/internal/sqlite/gen/log_event_policy_category_statuses.sql.go index 076d4a02..dabc0cdc 100644 --- a/internal/sqlite/gen/log_event_policy_category_statuses.sql.go +++ b/internal/sqlite/gen/log_event_policy_category_statuses.sql.go @@ -30,7 +30,7 @@ SELECT CAST(COALESCE(policy_pending_high_count, 0) AS INTEGER) AS policy_pending_high_count, CAST(COALESCE(policy_pending_medium_count, 0) AS INTEGER) AS policy_pending_medium_count, CAST(COALESCE(policy_pending_low_count, 0) AS INTEGER) AS policy_pending_low_count -FROM log_event_policy_category_statuses_cache +FROM recommendation_category_statuses_cache WHERE category IS NOT NULL AND category != '' AND category_type = ?1 ORDER BY estimated_cost_reduction_per_hour_usd DESC NULLS LAST, pending_count DESC diff --git a/internal/sqlite/gen/log_event_policy_statuses.sql.go b/internal/sqlite/gen/log_event_policy_statuses.sql.go index b6bb64d1..62637a92 100644 --- a/internal/sqlite/gen/log_event_policy_statuses.sql.go +++ b/internal/sqlite/gen/log_event_policy_statuses.sql.go @@ -10,7 +10,7 @@ import ( ) const countFixedPIIPolicies = `-- name: CountFixedPIIPolicies :one -SELECT CAST(COUNT(*) AS INTEGER) FROM log_event_policy_statuses_cache +SELECT CAST(COUNT(*) AS INTEGER) FROM recommendation_statuses_cache WHERE category = 'pii_leakage' AND status = 'APPROVED' ` @@ -25,16 +25,16 @@ const listPendingPIIPolicies = `-- name: ListPendingPIIPolicies :many SELECT COALESCE(service_name, '') AS service_name, COALESCE(log_event_name, '') AS log_event_name, - COALESCE(lep.analysis, '') AS analysis, - volume_per_hour, + COALESCE(ler.analysis, '') AS analysis, + current_events_per_hour AS volume_per_hour, CAST(COALESCE(( SELECT MAX(CASE json_extract(f.value, '$.observed') WHEN 1 THEN 1 ELSE 0 END) - FROM json_each(json_extract(lep.analysis, '$.pii_leakage.fields')) f + FROM json_each(json_extract(ler.analysis, '$.pii_leakage.fields')) f ), 0) AS INTEGER) AS any_observed -FROM log_event_policy_statuses_cache leps -LEFT JOIN log_event_policies lep ON lep.id = leps.policy_id +FROM recommendation_statuses_cache leps +LEFT JOIN log_event_recommendations ler ON ler.id = leps.recommendation_id WHERE leps.category = 'pii_leakage' AND leps.status = 'PENDING' -ORDER BY any_observed DESC, leps.volume_per_hour DESC +ORDER BY any_observed DESC, leps.current_events_per_hour DESC ` type ListPendingPIIPoliciesRow struct { @@ -78,16 +78,16 @@ const listTopPendingPoliciesByCategory = `-- name: ListTopPendingPoliciesByCateg SELECT COALESCE(service_name, '') AS service_name, COALESCE(log_event_name, '') AS log_event_name, - volume_per_hour, - bytes_per_hour, - estimated_cost_reduction_per_hour_usd AS estimated_cost_per_hour, - estimated_cost_reduction_per_hour_bytes_usd AS estimated_cost_per_hour_bytes, - estimated_cost_reduction_per_hour_volume_usd AS estimated_cost_per_hour_volume, - estimated_bytes_reduction_per_hour AS estimated_bytes_per_hour, - estimated_volume_reduction_per_hour AS estimated_volume_per_hour -FROM log_event_policy_statuses_cache + current_events_per_hour AS volume_per_hour, + current_bytes_per_hour AS bytes_per_hour, + impact_total_usd_per_hour AS estimated_cost_per_hour, + impact_bytes_usd_per_hour AS estimated_cost_per_hour_bytes, + impact_volume_usd_per_hour AS estimated_cost_per_hour_volume, + impact_bytes_per_hour AS estimated_bytes_per_hour, + impact_events_per_hour AS estimated_volume_per_hour +FROM recommendation_statuses_cache WHERE category = ?1 AND status = 'PENDING' -ORDER BY estimated_cost_reduction_per_hour_usd DESC, volume_per_hour DESC +ORDER BY impact_total_usd_per_hour DESC, current_events_per_hour DESC LIMIT ?2 ` diff --git a/internal/sqlite/gen/log_event_statuses.sql.go b/internal/sqlite/gen/log_event_statuses.sql.go index a8454883..b8beeec4 100644 --- a/internal/sqlite/gen/log_event_statuses.sql.go +++ b/internal/sqlite/gen/log_event_statuses.sql.go @@ -12,11 +12,11 @@ import ( const listLogEventStatusesByService = `-- name: ListLogEventStatusesByService :many SELECT COALESCE(le.name, '') AS log_event_name, - les.volume_per_hour, - les.bytes_per_hour, - les.cost_per_hour_usd, - CAST(COALESCE(les.pending_policy_count, 0) AS INTEGER) AS pending_policy_count, - CAST(COALESCE(les.approved_policy_count, 0) AS INTEGER) AS approved_policy_count, + les.current_events_per_hour AS volume_per_hour, + les.current_bytes_per_hour AS bytes_per_hour, + les.current_total_usd_per_hour AS cost_per_hour_usd, + CAST(COALESCE(les.pending_recommendation_count, 0) AS INTEGER) AS pending_policy_count, + CAST(COALESCE(les.approved_recommendation_count, 0) AS INTEGER) AS approved_policy_count, CAST(COALESCE(les.policy_pending_critical_count, 0) AS INTEGER) AS policy_pending_critical_count, CAST(COALESCE(les.policy_pending_high_count, 0) AS INTEGER) AS policy_pending_high_count, CAST(COALESCE(les.policy_pending_medium_count, 0) AS INTEGER) AS policy_pending_medium_count, @@ -25,7 +25,7 @@ FROM log_events le JOIN services s ON s.id = le.service_id LEFT JOIN log_event_statuses_cache les ON les.log_event_id = le.id WHERE s.name = ?1 -ORDER BY les.cost_per_hour_usd DESC, les.volume_per_hour DESC +ORDER BY les.current_total_usd_per_hour DESC, les.current_events_per_hour DESC LIMIT ?2 ` diff --git a/internal/sqlite/gen/models.go b/internal/sqlite/gen/models.go index 56484f63..d9d3bd6c 100644 --- a/internal/sqlite/gen/models.go +++ b/internal/sqlite/gen/models.go @@ -34,47 +34,43 @@ type DatadogAccount struct { } type DatadogAccountStatusesCache struct { - ID *string - AccountID *string - DatadogAccountID *string - DisabledServices *int64 - EstimatedBytesReductionPerHour *float64 - EstimatedCostReductionPerHourBytesUsd *float64 - EstimatedCostReductionPerHourUsd *float64 - EstimatedCostReductionPerHourVolumeUsd *float64 - EstimatedVolumeReductionPerHour *float64 - Health *string - InactiveServices *int64 - LogActiveServices *int64 - LogEventAnalyzedCount *int64 - LogEventBytesPerHour *float64 - LogEventCostPerHourBytesUsd *float64 - LogEventCostPerHourUsd *float64 - LogEventCostPerHourVolumeUsd *float64 - LogEventCount *int64 - LogEventVolumePerHour *float64 - LogServiceCount *int64 - ObservedBytesPerHourAfter *float64 - ObservedBytesPerHourBefore *float64 - ObservedCostPerHourAfterBytesUsd *float64 - ObservedCostPerHourAfterUsd *float64 - ObservedCostPerHourAfterVolumeUsd *float64 - ObservedCostPerHourBeforeBytesUsd *float64 - ObservedCostPerHourBeforeUsd *float64 - ObservedCostPerHourBeforeVolumeUsd *float64 - ObservedVolumePerHourAfter *float64 - ObservedVolumePerHourBefore *float64 - OkServices *int64 - PolicyApprovedCount *int64 - PolicyDismissedCount *int64 - PolicyPendingCount *int64 - PolicyPendingCriticalCount *int64 - PolicyPendingHighCount *int64 - PolicyPendingLowCount *int64 - PolicyPendingMediumCount *int64 - ReadyForUse *int64 - ServiceCostPerHourVolumeUsd *float64 - ServiceVolumePerHour *float64 + ID *string + AccountID *string + ApprovedRecommendationCount *int64 + CurrentBytesPerHour *float64 + CurrentBytesUsdPerHour *float64 + CurrentEventsPerHour *float64 + CurrentServiceEventsPerHour *float64 + CurrentServiceVolumeUsdPerHour *float64 + CurrentTotalUsdPerHour *float64 + CurrentVolumeUsdPerHour *float64 + DatadogAccountID *string + DisabledServices *int64 + DismissedRecommendationCount *int64 + EstimatedBytesPerHour *float64 + EstimatedBytesUsdPerHour *float64 + EstimatedEventsPerHour *float64 + EstimatedTotalUsdPerHour *float64 + EstimatedVolumeUsdPerHour *float64 + Health *string + ImpactBytesPerHour *float64 + ImpactBytesUsdPerHour *float64 + ImpactEventsPerHour *float64 + ImpactTotalUsdPerHour *float64 + ImpactVolumeUsdPerHour *float64 + InactiveServices *int64 + LogActiveServices *int64 + LogEventAnalyzedCount *int64 + LogEventCount *int64 + LogServiceCount *int64 + OkServices *int64 + PendingRecommendationCount *int64 + PolicyPendingCriticalCount *int64 + PolicyPendingHighCount *int64 + PolicyPendingLowCount *int64 + PolicyPendingMediumCount *int64 + ReadyForUse *int64 + RecommendationCount *int64 } type DatadogLogIndex struct { @@ -102,17 +98,7 @@ type LogEvent struct { SignalPurpose *string } -type LogEventField struct { - ID *string - AccountID *string - BaselineAvgBytes *float64 - CreatedAt *string - FieldPath *string - LogEventID *string - ValueDistribution *string -} - -type LogEventPolicy struct { +type LogEventRecommendation struct { ID *string AccountID *string Action *string @@ -132,7 +118,51 @@ type LogEventPolicy struct { WorkspaceID *string } -type LogEventPolicyCategoryStatusesCache struct { +type LogEventStatusesCache struct { + ID *string + AccountID *string + ApprovedRecommendationCount *int64 + CurrentBytesPerHour *float64 + CurrentBytesUsdPerHour *float64 + CurrentEventsPerHour *float64 + CurrentTotalUsdPerHour *float64 + CurrentVolumeUsdPerHour *float64 + DismissedRecommendationCount *int64 + EffectivePolicyEnabled *int64 + EstimatedBytesPerHour *float64 + EstimatedBytesUsdPerHour *float64 + EstimatedEventsPerHour *float64 + EstimatedTotalUsdPerHour *float64 + EstimatedVolumeUsdPerHour *float64 + HasBeenAnalyzed *int64 + HasVolumes *int64 + ImpactBytesPerHour *float64 + ImpactBytesUsdPerHour *float64 + ImpactEventsPerHour *float64 + ImpactTotalUsdPerHour *float64 + ImpactVolumeUsdPerHour *float64 + LogEventID *string + PendingRecommendationCount *int64 + PolicyPendingCriticalCount *int64 + PolicyPendingHighCount *int64 + PolicyPendingLowCount *int64 + PolicyPendingMediumCount *int64 + RecommendationCount *int64 + ServiceID *string +} + +type Message struct { + ID *string + AccountID *string + Content *string + ConversationID *string + CreatedAt *string + Model *string + Role *string + StopReason *string +} + +type RecommendationCategoryStatusesCache struct { ID *string AccountID *string Action *string @@ -158,80 +188,40 @@ type LogEventPolicyCategoryStatusesCache struct { TotalEventCount *int64 } -type LogEventPolicyStatusesCache struct { - ID *string - AccountID *string - Action *string - ApprovedAt *string - BytesPerHour *float64 - Category *string - CategoryType *string - CreatedAt *string - DismissedAt *string - EstimatedBytesReductionPerHour *float64 - EstimatedCostReductionPerHourBytesUsd *float64 - EstimatedCostReductionPerHourUsd *float64 - EstimatedCostReductionPerHourVolumeUsd *float64 - EstimatedVolumeReductionPerHour *float64 - LogEventID *string - LogEventName *string - PolicyID *string - ServiceID *string - ServiceName *string - Severity *string - Status *string - Subjective *int64 - SurvivalRate *float64 - VolumePerHour *float64 - WorkspaceID *string -} - -type LogEventStatusesCache struct { - ID *string - AccountID *string - ApprovedPolicyCount *int64 - BytesPerHour *float64 - CostPerHourBytesUsd *float64 - CostPerHourUsd *float64 - CostPerHourVolumeUsd *float64 - DismissedPolicyCount *int64 - EstimatedBytesReductionPerHour *float64 - EstimatedCostReductionPerHourBytesUsd *float64 - EstimatedCostReductionPerHourUsd *float64 - EstimatedCostReductionPerHourVolumeUsd *float64 - EstimatedVolumeReductionPerHour *float64 - HasBeenAnalyzed *int64 - HasVolumes *int64 - LogEventID *string - ObservedBytesPerHourAfter *float64 - ObservedBytesPerHourBefore *float64 - ObservedCostPerHourAfterBytesUsd *float64 - ObservedCostPerHourAfterUsd *float64 - ObservedCostPerHourAfterVolumeUsd *float64 - ObservedCostPerHourBeforeBytesUsd *float64 - ObservedCostPerHourBeforeUsd *float64 - ObservedCostPerHourBeforeVolumeUsd *float64 - ObservedVolumePerHourAfter *float64 - ObservedVolumePerHourBefore *float64 - PendingPolicyCount *int64 - PolicyCount *int64 - PolicyPendingCriticalCount *int64 - PolicyPendingHighCount *int64 - PolicyPendingLowCount *int64 - PolicyPendingMediumCount *int64 - ServiceID *string - VolumePerHour *float64 -} - -type Message struct { - ID *string - AccountID *string - Content *string - ConversationID *string - CreatedAt *string - Model *string - Role *string - StopReason *string +type RecommendationStatusesCache struct { + ID *string + AccountID *string + Action *string + ApprovedAt *string + Category *string + CategoryType *string + CreatedAt *string + CurrentBytesPerHour *float64 + CurrentBytesUsdPerHour *float64 + CurrentEventsPerHour *float64 + CurrentTotalUsdPerHour *float64 + CurrentVolumeUsdPerHour *float64 + DismissedAt *string + EstimatedBytesPerHour *float64 + EstimatedBytesUsdPerHour *float64 + EstimatedEventsPerHour *float64 + EstimatedTotalUsdPerHour *float64 + EstimatedVolumeUsdPerHour *float64 + ImpactBytesPerHour *float64 + ImpactBytesUsdPerHour *float64 + ImpactEventsPerHour *float64 + ImpactTotalUsdPerHour *float64 + ImpactVolumeUsdPerHour *float64 + LogEventID *string + LogEventName *string + RecommendationID *string + ServiceID *string + ServiceName *string + Severity *string + Status *string + Subjective *int64 + SurvivalRate *float64 + WorkspaceID *string } type Service struct { @@ -245,47 +235,43 @@ type Service struct { } type ServiceStatusesCache struct { - ID *string - AccountID *string - DatadogAccountID *string - EstimatedBytesReductionPerHour *float64 - EstimatedCostReductionPerHourBytesUsd *float64 - EstimatedCostReductionPerHourUsd *float64 - EstimatedCostReductionPerHourVolumeUsd *float64 - EstimatedVolumeReductionPerHour *float64 - Health *string - LogEventAnalyzedCount *int64 - LogEventBytesPerHour *float64 - LogEventCostPerHourBytesUsd *float64 - LogEventCostPerHourUsd *float64 - LogEventCostPerHourVolumeUsd *float64 - LogEventCount *int64 - LogEventVolumePerHour *float64 - ObservedBytesPerHourAfter *float64 - ObservedBytesPerHourBefore *float64 - ObservedCostPerHourAfterBytesUsd *float64 - ObservedCostPerHourAfterUsd *float64 - ObservedCostPerHourAfterVolumeUsd *float64 - ObservedCostPerHourBeforeBytesUsd *float64 - ObservedCostPerHourBeforeUsd *float64 - ObservedCostPerHourBeforeVolumeUsd *float64 - ObservedVolumePerHourAfter *float64 - ObservedVolumePerHourBefore *float64 - PolicyApprovedCount *int64 - PolicyDismissedCount *int64 - PolicyPendingCount *int64 - PolicyPendingCriticalCount *int64 - PolicyPendingHighCount *int64 - PolicyPendingLowCount *int64 - PolicyPendingMediumCount *int64 - ServiceCostPerHourVolumeUsd *float64 - ServiceDebugVolumePerHour *float64 - ServiceErrorVolumePerHour *float64 - ServiceID *string - ServiceInfoVolumePerHour *float64 - ServiceOtherVolumePerHour *float64 - ServiceVolumePerHour *float64 - ServiceWarnVolumePerHour *float64 + ID *string + AccountID *string + ApprovedRecommendationCount *int64 + CurrentBytesPerHour *float64 + CurrentBytesUsdPerHour *float64 + CurrentEventsPerHour *float64 + CurrentServiceDebugEventsPerHour *float64 + CurrentServiceErrorEventsPerHour *float64 + CurrentServiceEventsPerHour *float64 + CurrentServiceInfoEventsPerHour *float64 + CurrentServiceOtherEventsPerHour *float64 + CurrentServiceVolumeUsdPerHour *float64 + CurrentServiceWarnEventsPerHour *float64 + CurrentTotalUsdPerHour *float64 + CurrentVolumeUsdPerHour *float64 + DatadogAccountID *string + DismissedRecommendationCount *int64 + EstimatedBytesPerHour *float64 + EstimatedBytesUsdPerHour *float64 + EstimatedEventsPerHour *float64 + EstimatedTotalUsdPerHour *float64 + EstimatedVolumeUsdPerHour *float64 + Health *string + ImpactBytesPerHour *float64 + ImpactBytesUsdPerHour *float64 + ImpactEventsPerHour *float64 + ImpactTotalUsdPerHour *float64 + ImpactVolumeUsdPerHour *float64 + LogEventAnalyzedCount *int64 + LogEventCount *int64 + PendingRecommendationCount *int64 + PolicyPendingCriticalCount *int64 + PolicyPendingHighCount *int64 + PolicyPendingLowCount *int64 + PolicyPendingMediumCount *int64 + RecommendationCount *int64 + ServiceID *string } type Team struct { diff --git a/internal/sqlite/gen/policy_cards.sql.go b/internal/sqlite/gen/policy_cards.sql.go index d80d7bfe..dbdf450f 100644 --- a/internal/sqlite/gen/policy_cards.sql.go +++ b/internal/sqlite/gen/policy_cards.sql.go @@ -11,31 +11,31 @@ import ( const getPolicyCard = `-- name: GetPolicyCard :one SELECT - COALESCE(ps.policy_id, '') AS policy_id, + COALESCE(ps.recommendation_id, '') AS policy_id, COALESCE(ps.service_name, '') AS service_name, COALESCE(ps.log_event_name, '') AS log_event_name, COALESCE(ps.category, '') AS category, COALESCE(ps.category_type, '') AS category_type, COALESCE(ps.action, '') AS "action", COALESCE(ps.status, '') AS status, - ps.volume_per_hour, - ps.bytes_per_hour, - ps.estimated_cost_reduction_per_hour_usd AS estimated_cost_per_hour, - ps.estimated_volume_reduction_per_hour AS estimated_volume_per_hour, - ps.estimated_bytes_reduction_per_hour AS estimated_bytes_per_hour, + ps.current_events_per_hour AS volume_per_hour, + ps.current_bytes_per_hour AS bytes_per_hour, + ps.impact_total_usd_per_hour AS estimated_cost_per_hour, + ps.impact_events_per_hour AS estimated_volume_per_hour, + ps.impact_bytes_per_hour AS estimated_bytes_per_hour, COALESCE(ps.severity, '') AS severity, ps.survival_rate, COALESCE(cat.display_name, '') AS category_display_name, - COALESCE(lep.analysis, '') AS analysis, + COALESCE(ler.analysis, '') AS analysis, COALESCE(le.examples, '') AS examples, le.baseline_avg_bytes AS event_baseline_avg_bytes, le.baseline_volume_per_hour AS event_baseline_volume_per_hour, COALESCE(ps.log_event_id, '') AS log_event_id -FROM log_event_policy_statuses_cache ps -LEFT JOIN log_event_policy_category_statuses_cache cat ON cat.category = ps.category -LEFT JOIN log_event_policies lep ON lep.id = ps.policy_id +FROM recommendation_statuses_cache ps +LEFT JOIN recommendation_category_statuses_cache cat ON cat.category = ps.category +LEFT JOIN log_event_recommendations ler ON ler.id = ps.recommendation_id LEFT JOIN log_events le ON le.id = ps.log_event_id -WHERE ps.policy_id = ?1 +WHERE ps.recommendation_id = ?1 ` type GetPolicyCardRow struct { @@ -62,10 +62,10 @@ type GetPolicyCardRow struct { } // Fetches a single policy with all context needed for rich card rendering. -// Main table: log_event_policy_statuses_cache (denormalized policy + metrics). +// Main table: recommendation_statuses_cache (denormalized recommendation + metrics). // JOINs enrich with: category display name, AI analysis, log examples, baselines. -func (q *Queries) GetPolicyCard(ctx context.Context, policyID *string) (GetPolicyCardRow, error) { - row := q.db.QueryRowContext(ctx, getPolicyCard, policyID) +func (q *Queries) GetPolicyCard(ctx context.Context, recommendationID *string) (GetPolicyCardRow, error) { + row := q.db.QueryRowContext(ctx, getPolicyCard, recommendationID) var i GetPolicyCardRow err := row.Scan( &i.PolicyID, @@ -94,22 +94,21 @@ func (q *Queries) GetPolicyCard(ctx context.Context, policyID *string) (GetPolic const listFieldsByLogEvent = `-- name: ListFieldsByLogEvent :many SELECT - COALESCE(field_path, '') AS field_path, - baseline_avg_bytes -FROM log_event_fields -WHERE log_event_id = ?1 -ORDER BY baseline_avg_bytes DESC + '' AS field_path, + CAST(NULL AS REAL) AS baseline_avg_bytes +FROM log_events +WHERE id = ?1 AND 1 = 0 ` type ListFieldsByLogEventRow struct { FieldPath string - BaselineAvgBytes *float64 + BaselineAvgBytes float64 } // Returns per-field metadata for a log event, used to show per-field byte impact // in quality policies (instrumentation_bloat, oversized_fields, duplicate_fields). -func (q *Queries) ListFieldsByLogEvent(ctx context.Context, logEventID *string) ([]ListFieldsByLogEventRow, error) { - rows, err := q.db.QueryContext(ctx, listFieldsByLogEvent, logEventID) +func (q *Queries) ListFieldsByLogEvent(ctx context.Context, id *string) ([]ListFieldsByLogEventRow, error) { + rows, err := q.db.QueryContext(ctx, listFieldsByLogEvent, id) if err != nil { return nil, err } diff --git a/internal/sqlite/gen/querier.go b/internal/sqlite/gen/querier.go index 02a3dcf1..9ced1689 100644 --- a/internal/sqlite/gen/querier.go +++ b/internal/sqlite/gen/querier.go @@ -9,10 +9,8 @@ import ( ) type Querier interface { - ApproveLogEventPolicy(ctx context.Context, arg ApproveLogEventPolicyParams) error CountConversations(ctx context.Context) (int64, error) CountFixedPIIPolicies(ctx context.Context) (int64, error) - CountLogEventPolicies(ctx context.Context) (int64, error) CountLogEvents(ctx context.Context) (int64, error) CountMessages(ctx context.Context) (int64, error) CountMessagesByConversation(ctx context.Context, conversationID *string) (int64, error) @@ -20,16 +18,15 @@ type Querier interface { CountObservedPoliciesByComplianceCategory(ctx context.Context) ([]CountObservedPoliciesByComplianceCategoryRow, error) CountServices(ctx context.Context) (int64, error) DeleteMessage(ctx context.Context, id *string) error - DismissLogEventPolicy(ctx context.Context, arg DismissLogEventPolicyParams) error GetAccountSummary(ctx context.Context) (GetAccountSummaryRow, error) GetConversation(ctx context.Context, id *string) (Conversation, error) GetLatestConversationByAccount(ctx context.Context, accountID *string) (Conversation, error) GetLatestMessageByConversation(ctx context.Context, conversationID *string) (Message, error) GetMessage(ctx context.Context, id *string) (Message, error) // Fetches a single policy with all context needed for rich card rendering. - // Main table: log_event_policy_statuses_cache (denormalized policy + metrics). + // Main table: recommendation_statuses_cache (denormalized recommendation + metrics). // JOINs enrich with: category display name, AI analysis, log examples, baselines. - GetPolicyCard(ctx context.Context, policyID *string) (GetPolicyCardRow, error) + GetPolicyCard(ctx context.Context, recommendationID *string) (GetPolicyCardRow, error) GetService(ctx context.Context, id *string) (Service, error) InsertConversation(ctx context.Context, arg InsertConversationParams) error InsertMessage(ctx context.Context, arg InsertMessageParams) error @@ -40,7 +37,7 @@ type Querier interface { ListEnabledServiceStatuses(ctx context.Context, rowLimit int64) ([]ListEnabledServiceStatusesRow, error) // Returns per-field metadata for a log event, used to show per-field byte impact // in quality policies (instrumentation_bloat, oversized_fields, duplicate_fields). - ListFieldsByLogEvent(ctx context.Context, logEventID *string) ([]ListFieldsByLogEventRow, error) + ListFieldsByLogEvent(ctx context.Context, id *string) ([]ListFieldsByLogEventRow, error) ListLogEventStatusesByService(ctx context.Context, arg ListLogEventStatusesByServiceParams) ([]ListLogEventStatusesByServiceRow, error) ListMessagesByConversation(ctx context.Context, conversationID *string) ([]Message, error) ListMessagesByConversationDesc(ctx context.Context, conversationID *string) ([]Message, error) diff --git a/internal/sqlite/gen/service_statuses.sql.go b/internal/sqlite/gen/service_statuses.sql.go index b748e219..715050af 100644 --- a/internal/sqlite/gen/service_statuses.sql.go +++ b/internal/sqlite/gen/service_statuses.sql.go @@ -15,40 +15,40 @@ SELECT COALESCE(ssc.health, '') AS health, CAST(COALESCE(ssc.log_event_count, 0) AS INTEGER) AS log_event_count, CAST(COALESCE(ssc.log_event_analyzed_count, 0) AS INTEGER) AS log_event_analyzed_count, - CAST(COALESCE(ssc.policy_pending_count, 0) AS INTEGER) AS policy_pending_count, - CAST(COALESCE(ssc.policy_approved_count, 0) AS INTEGER) AS policy_approved_count, - CAST(COALESCE(ssc.policy_dismissed_count, 0) AS INTEGER) AS policy_dismissed_count, + CAST(COALESCE(ssc.pending_recommendation_count, 0) AS INTEGER) AS policy_pending_count, + CAST(COALESCE(ssc.approved_recommendation_count, 0) AS INTEGER) AS policy_approved_count, + CAST(COALESCE(ssc.dismissed_recommendation_count, 0) AS INTEGER) AS policy_dismissed_count, CAST(COALESCE(ssc.policy_pending_critical_count, 0) AS INTEGER) AS policy_pending_critical_count, CAST(COALESCE(ssc.policy_pending_high_count, 0) AS INTEGER) AS policy_pending_high_count, CAST(COALESCE(ssc.policy_pending_medium_count, 0) AS INTEGER) AS policy_pending_medium_count, CAST(COALESCE(ssc.policy_pending_low_count, 0) AS INTEGER) AS policy_pending_low_count, - ssc.service_volume_per_hour, - ssc.service_debug_volume_per_hour, - ssc.service_info_volume_per_hour, - ssc.service_warn_volume_per_hour, - ssc.service_error_volume_per_hour, - ssc.service_other_volume_per_hour, - ssc.service_cost_per_hour_volume_usd, - ssc.log_event_volume_per_hour, - ssc.log_event_bytes_per_hour, - ssc.log_event_cost_per_hour_usd, - ssc.log_event_cost_per_hour_bytes_usd, - ssc.log_event_cost_per_hour_volume_usd, - ssc.estimated_volume_reduction_per_hour, - ssc.estimated_bytes_reduction_per_hour, - ssc.estimated_cost_reduction_per_hour_usd, - ssc.estimated_cost_reduction_per_hour_bytes_usd, - ssc.estimated_cost_reduction_per_hour_volume_usd, - ssc.observed_volume_per_hour_before, - ssc.observed_volume_per_hour_after, - ssc.observed_bytes_per_hour_before, - ssc.observed_bytes_per_hour_after, - ssc.observed_cost_per_hour_before_usd, - ssc.observed_cost_per_hour_before_bytes_usd, - ssc.observed_cost_per_hour_before_volume_usd, - ssc.observed_cost_per_hour_after_usd, - ssc.observed_cost_per_hour_after_bytes_usd, - ssc.observed_cost_per_hour_after_volume_usd + ssc.current_service_events_per_hour AS service_volume_per_hour, + ssc.current_service_debug_events_per_hour AS service_debug_volume_per_hour, + ssc.current_service_info_events_per_hour AS service_info_volume_per_hour, + ssc.current_service_warn_events_per_hour AS service_warn_volume_per_hour, + ssc.current_service_error_events_per_hour AS service_error_volume_per_hour, + ssc.current_service_other_events_per_hour AS service_other_volume_per_hour, + ssc.current_service_volume_usd_per_hour AS service_cost_per_hour_volume_usd, + ssc.current_events_per_hour AS log_event_volume_per_hour, + ssc.current_bytes_per_hour AS log_event_bytes_per_hour, + ssc.current_total_usd_per_hour AS log_event_cost_per_hour_usd, + ssc.current_bytes_usd_per_hour AS log_event_cost_per_hour_bytes_usd, + ssc.current_volume_usd_per_hour AS log_event_cost_per_hour_volume_usd, + ssc.impact_events_per_hour AS estimated_volume_reduction_per_hour, + ssc.impact_bytes_per_hour AS estimated_bytes_reduction_per_hour, + ssc.impact_total_usd_per_hour AS estimated_cost_reduction_per_hour_usd, + ssc.impact_bytes_usd_per_hour AS estimated_cost_reduction_per_hour_bytes_usd, + ssc.impact_volume_usd_per_hour AS estimated_cost_reduction_per_hour_volume_usd, + ssc.current_events_per_hour AS observed_volume_per_hour_before, + CAST((ssc.current_events_per_hour - ssc.impact_events_per_hour) AS REAL) AS observed_volume_per_hour_after, + ssc.current_bytes_per_hour AS observed_bytes_per_hour_before, + CAST((ssc.current_bytes_per_hour - ssc.impact_bytes_per_hour) AS REAL) AS observed_bytes_per_hour_after, + ssc.current_total_usd_per_hour AS observed_cost_per_hour_before_usd, + ssc.current_bytes_usd_per_hour AS observed_cost_per_hour_before_bytes_usd, + ssc.current_volume_usd_per_hour AS observed_cost_per_hour_before_volume_usd, + CAST((ssc.current_total_usd_per_hour - ssc.impact_total_usd_per_hour) AS REAL) AS observed_cost_per_hour_after_usd, + CAST((ssc.current_bytes_usd_per_hour - ssc.impact_bytes_usd_per_hour) AS REAL) AS observed_cost_per_hour_after_bytes_usd, + CAST((ssc.current_volume_usd_per_hour - ssc.impact_volume_usd_per_hour) AS REAL) AS observed_cost_per_hour_after_volume_usd FROM service_statuses_cache ssc JOIN services s ON ssc.service_id = s.id ORDER BY @@ -58,7 +58,7 @@ ORDER BY WHEN 'INACTIVE' THEN 3 ELSE 4 END, - ssc.log_event_cost_per_hour_usd DESC, + ssc.current_total_usd_per_hour DESC, s.name ` @@ -92,15 +92,15 @@ type ListAllServiceStatusesRow struct { EstimatedCostReductionPerHourBytesUsd *float64 EstimatedCostReductionPerHourVolumeUsd *float64 ObservedVolumePerHourBefore *float64 - ObservedVolumePerHourAfter *float64 + ObservedVolumePerHourAfter float64 ObservedBytesPerHourBefore *float64 - ObservedBytesPerHourAfter *float64 + ObservedBytesPerHourAfter float64 ObservedCostPerHourBeforeUsd *float64 ObservedCostPerHourBeforeBytesUsd *float64 ObservedCostPerHourBeforeVolumeUsd *float64 - ObservedCostPerHourAfterUsd *float64 - ObservedCostPerHourAfterBytesUsd *float64 - ObservedCostPerHourAfterVolumeUsd *float64 + ObservedCostPerHourAfterUsd float64 + ObservedCostPerHourAfterBytesUsd float64 + ObservedCostPerHourAfterVolumeUsd float64 } func (q *Queries) ListAllServiceStatuses(ctx context.Context) ([]ListAllServiceStatusesRow, error) { @@ -171,40 +171,40 @@ SELECT COALESCE(ssc.health, '') AS health, CAST(COALESCE(ssc.log_event_count, 0) AS INTEGER) AS log_event_count, CAST(COALESCE(ssc.log_event_analyzed_count, 0) AS INTEGER) AS log_event_analyzed_count, - CAST(COALESCE(ssc.policy_pending_count, 0) AS INTEGER) AS policy_pending_count, - CAST(COALESCE(ssc.policy_approved_count, 0) AS INTEGER) AS policy_approved_count, - CAST(COALESCE(ssc.policy_dismissed_count, 0) AS INTEGER) AS policy_dismissed_count, + CAST(COALESCE(ssc.pending_recommendation_count, 0) AS INTEGER) AS policy_pending_count, + CAST(COALESCE(ssc.approved_recommendation_count, 0) AS INTEGER) AS policy_approved_count, + CAST(COALESCE(ssc.dismissed_recommendation_count, 0) AS INTEGER) AS policy_dismissed_count, CAST(COALESCE(ssc.policy_pending_critical_count, 0) AS INTEGER) AS policy_pending_critical_count, CAST(COALESCE(ssc.policy_pending_high_count, 0) AS INTEGER) AS policy_pending_high_count, CAST(COALESCE(ssc.policy_pending_medium_count, 0) AS INTEGER) AS policy_pending_medium_count, CAST(COALESCE(ssc.policy_pending_low_count, 0) AS INTEGER) AS policy_pending_low_count, - ssc.service_volume_per_hour, - ssc.service_debug_volume_per_hour, - ssc.service_info_volume_per_hour, - ssc.service_warn_volume_per_hour, - ssc.service_error_volume_per_hour, - ssc.service_other_volume_per_hour, - ssc.service_cost_per_hour_volume_usd, - ssc.log_event_volume_per_hour, - ssc.log_event_bytes_per_hour, - ssc.log_event_cost_per_hour_usd, - ssc.log_event_cost_per_hour_bytes_usd, - ssc.log_event_cost_per_hour_volume_usd, - ssc.estimated_volume_reduction_per_hour, - ssc.estimated_bytes_reduction_per_hour, - ssc.estimated_cost_reduction_per_hour_usd, - ssc.estimated_cost_reduction_per_hour_bytes_usd, - ssc.estimated_cost_reduction_per_hour_volume_usd, - ssc.observed_volume_per_hour_before, - ssc.observed_volume_per_hour_after, - ssc.observed_bytes_per_hour_before, - ssc.observed_bytes_per_hour_after, - ssc.observed_cost_per_hour_before_usd, - ssc.observed_cost_per_hour_before_bytes_usd, - ssc.observed_cost_per_hour_before_volume_usd, - ssc.observed_cost_per_hour_after_usd, - ssc.observed_cost_per_hour_after_bytes_usd, - ssc.observed_cost_per_hour_after_volume_usd + ssc.current_service_events_per_hour AS service_volume_per_hour, + ssc.current_service_debug_events_per_hour AS service_debug_volume_per_hour, + ssc.current_service_info_events_per_hour AS service_info_volume_per_hour, + ssc.current_service_warn_events_per_hour AS service_warn_volume_per_hour, + ssc.current_service_error_events_per_hour AS service_error_volume_per_hour, + ssc.current_service_other_events_per_hour AS service_other_volume_per_hour, + ssc.current_service_volume_usd_per_hour AS service_cost_per_hour_volume_usd, + ssc.current_events_per_hour AS log_event_volume_per_hour, + ssc.current_bytes_per_hour AS log_event_bytes_per_hour, + ssc.current_total_usd_per_hour AS log_event_cost_per_hour_usd, + ssc.current_bytes_usd_per_hour AS log_event_cost_per_hour_bytes_usd, + ssc.current_volume_usd_per_hour AS log_event_cost_per_hour_volume_usd, + ssc.impact_events_per_hour AS estimated_volume_reduction_per_hour, + ssc.impact_bytes_per_hour AS estimated_bytes_reduction_per_hour, + ssc.impact_total_usd_per_hour AS estimated_cost_reduction_per_hour_usd, + ssc.impact_bytes_usd_per_hour AS estimated_cost_reduction_per_hour_bytes_usd, + ssc.impact_volume_usd_per_hour AS estimated_cost_reduction_per_hour_volume_usd, + ssc.current_events_per_hour AS observed_volume_per_hour_before, + CAST((ssc.current_events_per_hour - ssc.impact_events_per_hour) AS REAL) AS observed_volume_per_hour_after, + ssc.current_bytes_per_hour AS observed_bytes_per_hour_before, + CAST((ssc.current_bytes_per_hour - ssc.impact_bytes_per_hour) AS REAL) AS observed_bytes_per_hour_after, + ssc.current_total_usd_per_hour AS observed_cost_per_hour_before_usd, + ssc.current_bytes_usd_per_hour AS observed_cost_per_hour_before_bytes_usd, + ssc.current_volume_usd_per_hour AS observed_cost_per_hour_before_volume_usd, + CAST((ssc.current_total_usd_per_hour - ssc.impact_total_usd_per_hour) AS REAL) AS observed_cost_per_hour_after_usd, + CAST((ssc.current_bytes_usd_per_hour - ssc.impact_bytes_usd_per_hour) AS REAL) AS observed_cost_per_hour_after_bytes_usd, + CAST((ssc.current_volume_usd_per_hour - ssc.impact_volume_usd_per_hour) AS REAL) AS observed_cost_per_hour_after_volume_usd FROM service_statuses_cache ssc JOIN services s ON ssc.service_id = s.id WHERE ssc.health NOT IN ('DISABLED', 'INACTIVE') @@ -213,7 +213,7 @@ ORDER BY WHEN 'OK' THEN 1 ELSE 2 END, - ssc.log_event_cost_per_hour_usd DESC, + ssc.current_total_usd_per_hour DESC, s.name LIMIT ?1 ` @@ -248,15 +248,15 @@ type ListEnabledServiceStatusesRow struct { EstimatedCostReductionPerHourBytesUsd *float64 EstimatedCostReductionPerHourVolumeUsd *float64 ObservedVolumePerHourBefore *float64 - ObservedVolumePerHourAfter *float64 + ObservedVolumePerHourAfter float64 ObservedBytesPerHourBefore *float64 - ObservedBytesPerHourAfter *float64 + ObservedBytesPerHourAfter float64 ObservedCostPerHourBeforeUsd *float64 ObservedCostPerHourBeforeBytesUsd *float64 ObservedCostPerHourBeforeVolumeUsd *float64 - ObservedCostPerHourAfterUsd *float64 - ObservedCostPerHourAfterBytesUsd *float64 - ObservedCostPerHourAfterVolumeUsd *float64 + ObservedCostPerHourAfterUsd float64 + ObservedCostPerHourAfterBytesUsd float64 + ObservedCostPerHourAfterVolumeUsd float64 } func (q *Queries) ListEnabledServiceStatuses(ctx context.Context, rowLimit int64) ([]ListEnabledServiceStatusesRow, error) { diff --git a/internal/sqlite/log_event_policy_statuses.go b/internal/sqlite/log_event_policy_statuses.go index fe26736e..bd660c0f 100644 --- a/internal/sqlite/log_event_policy_statuses.go +++ b/internal/sqlite/log_event_policy_statuses.go @@ -2,6 +2,8 @@ package sqlite import ( "context" + "fmt" + "strconv" "github.com/usetero/cli/internal/domain" "github.com/usetero/cli/internal/sqlite/gen" @@ -64,11 +66,13 @@ func (l *logEventPolicyStatusesImpl) fieldSizes(ctx context.Context, logEventID sizes := make(map[string]float64, len(rows)) for _, row := range rows { - if row.BaselineAvgBytes != nil { - fp := domain.ParseFieldPathPg(row.FieldPath) - if !fp.IsEmpty() { - sizes[fp.Key()] = *row.BaselineAvgBytes - } + baseline, ok := toFloat64(row.BaselineAvgBytes) + if !ok { + continue + } + fp := domain.ParseFieldPathPg(row.FieldPath) + if !fp.IsEmpty() { + sizes[fp.Key()] = baseline } } if len(sizes) == 0 { @@ -77,6 +81,30 @@ func (l *logEventPolicyStatusesImpl) fieldSizes(ctx context.Context, logEventID return sizes } +func toFloat64(v interface{}) (float64, bool) { + switch t := v.(type) { + case nil: + return 0, false + case float64: + return t, true + case float32: + return float64(t), true + case int64: + return float64(t), true + case int: + return float64(t), true + case []byte: + n, err := strconv.ParseFloat(string(t), 64) + return n, err == nil + case string: + n, err := strconv.ParseFloat(t, 64) + return n, err == nil + default: + n, err := strconv.ParseFloat(fmt.Sprint(t), 64) + return n, err == nil + } +} + func (l *logEventPolicyStatusesImpl) ListTopPendingPoliciesByCategory(ctx context.Context, category domain.PolicyCategory, limit int64) ([]domain.WastePolicy, error) { catStr := string(category) rows, err := l.queries.ListTopPendingPoliciesByCategory(ctx, gen.ListTopPendingPoliciesByCategoryParams{ diff --git a/internal/sqlite/queries/compliance_policies.sql b/internal/sqlite/queries/compliance_policies.sql index 48697fa0..ab23d642 100644 --- a/internal/sqlite/queries/compliance_policies.sql +++ b/internal/sqlite/queries/compliance_policies.sql @@ -6,18 +6,18 @@ SELECT COALESCE(s.name, '') AS service_name, COALESCE(le.name, '') AS log_event_name, COALESCE(lep.analysis, '') AS analysis, - les.volume_per_hour, + les.current_events_per_hour AS volume_per_hour, CAST(COALESCE(( SELECT MAX(CASE json_extract(f.value, '$.observed') WHEN 1 THEN 1 ELSE 0 END) FROM json_each(json_extract(lep.analysis, '$.' || ?1 || '.fields')) f ), 0) AS INTEGER) AS any_observed -FROM log_event_policy_statuses_cache leps +FROM recommendation_statuses_cache leps JOIN log_events le ON le.id = leps.log_event_id JOIN services s ON s.id = le.service_id -LEFT JOIN log_event_policies lep ON lep.id = leps.policy_id +LEFT JOIN log_event_recommendations lep ON lep.id = leps.recommendation_id LEFT JOIN log_event_statuses_cache les ON les.log_event_id = leps.log_event_id WHERE leps.category = ?1 AND leps.status = 'PENDING' -ORDER BY any_observed DESC, les.volume_per_hour DESC +ORDER BY any_observed DESC, les.current_events_per_hour DESC LIMIT ?2; -- name: CountObservedPoliciesByComplianceCategory :many @@ -28,7 +28,7 @@ SELECT SELECT MAX(CASE json_extract(f.value, '$.observed') WHEN 1 THEN 1 ELSE 0 END) FROM json_each(json_extract(lep.analysis, '$.' || leps.category || '.fields')) f ), 0) = 1 THEN 1 ELSE 0 END) AS INTEGER) AS observed_count -FROM log_event_policy_statuses_cache leps -LEFT JOIN log_event_policies lep ON lep.id = leps.policy_id +FROM recommendation_statuses_cache leps +LEFT JOIN log_event_recommendations lep ON lep.id = leps.recommendation_id WHERE leps.category_type = 'compliance' AND leps.status = 'PENDING' GROUP BY leps.category; diff --git a/internal/sqlite/queries/datadog_account_statuses.sql b/internal/sqlite/queries/datadog_account_statuses.sql index 5f44d0c6..73f53582 100644 --- a/internal/sqlite/queries/datadog_account_statuses.sql +++ b/internal/sqlite/queries/datadog_account_statuses.sql @@ -18,41 +18,41 @@ SELECT CAST(COALESCE(SUM(log_event_analyzed_count), 0) AS INTEGER) AS analyzed_count, -- policies - CAST(COALESCE(SUM(policy_pending_count), 0) AS INTEGER) AS pending_policy_count, - CAST(COALESCE(SUM(policy_approved_count), 0) AS INTEGER) AS approved_policy_count, - CAST(COALESCE(SUM(policy_dismissed_count), 0) AS INTEGER) AS dismissed_policy_count, + CAST(COALESCE(SUM(pending_recommendation_count), 0) AS INTEGER) AS pending_policy_count, + CAST(COALESCE(SUM(approved_recommendation_count), 0) AS INTEGER) AS approved_policy_count, + CAST(COALESCE(SUM(dismissed_recommendation_count), 0) AS INTEGER) AS dismissed_policy_count, CAST(COALESCE(SUM(policy_pending_critical_count), 0) AS INTEGER) AS policy_pending_critical_count, CAST(COALESCE(SUM(policy_pending_high_count), 0) AS INTEGER) AS policy_pending_high_count, CAST(COALESCE(SUM(policy_pending_medium_count), 0) AS INTEGER) AS policy_pending_medium_count, CAST(COALESCE(SUM(policy_pending_low_count), 0) AS INTEGER) AS policy_pending_low_count, -- estimated savings - SUM(estimated_cost_reduction_per_hour_usd) AS estimated_cost_per_hour, - SUM(estimated_cost_reduction_per_hour_bytes_usd) AS estimated_cost_per_hour_bytes, - SUM(estimated_cost_reduction_per_hour_volume_usd) AS estimated_cost_per_hour_volume, - SUM(estimated_volume_reduction_per_hour) AS estimated_volume_per_hour, - SUM(estimated_bytes_reduction_per_hour) AS estimated_bytes_per_hour, + SUM(impact_total_usd_per_hour) AS estimated_cost_per_hour, + SUM(impact_bytes_usd_per_hour) AS estimated_cost_per_hour_bytes, + SUM(impact_volume_usd_per_hour) AS estimated_cost_per_hour_volume, + SUM(impact_events_per_hour) AS estimated_volume_per_hour, + SUM(impact_bytes_per_hour) AS estimated_bytes_per_hour, -- observed impact - SUM(observed_cost_per_hour_before_usd) AS observed_cost_before, - SUM(observed_cost_per_hour_before_bytes_usd) AS observed_cost_before_bytes, - SUM(observed_cost_per_hour_before_volume_usd) AS observed_cost_before_volume, - SUM(observed_cost_per_hour_after_usd) AS observed_cost_after, - SUM(observed_cost_per_hour_after_bytes_usd) AS observed_cost_after_bytes, - SUM(observed_cost_per_hour_after_volume_usd) AS observed_cost_after_volume, - SUM(observed_volume_per_hour_before) AS observed_volume_before, - SUM(observed_volume_per_hour_after) AS observed_volume_after, - SUM(observed_bytes_per_hour_before) AS observed_bytes_before, - SUM(observed_bytes_per_hour_after) AS observed_bytes_after, + SUM(current_total_usd_per_hour) AS observed_cost_before, + SUM(current_bytes_usd_per_hour) AS observed_cost_before_bytes, + SUM(current_volume_usd_per_hour) AS observed_cost_before_volume, + SUM(current_total_usd_per_hour - impact_total_usd_per_hour) AS observed_cost_after, + SUM(current_bytes_usd_per_hour - impact_bytes_usd_per_hour) AS observed_cost_after_bytes, + SUM(current_volume_usd_per_hour - impact_volume_usd_per_hour) AS observed_cost_after_volume, + SUM(current_events_per_hour) AS observed_volume_before, + SUM(current_events_per_hour - impact_events_per_hour) AS observed_volume_after, + SUM(current_bytes_per_hour) AS observed_bytes_before, + SUM(current_bytes_per_hour - impact_bytes_per_hour) AS observed_bytes_after, -- totals - SUM(log_event_cost_per_hour_usd) AS total_cost_per_hour, - SUM(log_event_cost_per_hour_bytes_usd) AS total_cost_per_hour_bytes, - SUM(log_event_cost_per_hour_volume_usd) AS total_cost_per_hour_volume, - SUM(log_event_volume_per_hour) AS total_volume_per_hour, - SUM(log_event_bytes_per_hour) AS total_bytes_per_hour, + SUM(current_total_usd_per_hour) AS total_cost_per_hour, + SUM(current_bytes_usd_per_hour) AS total_cost_per_hour_bytes, + SUM(current_volume_usd_per_hour) AS total_cost_per_hour_volume, + SUM(current_events_per_hour) AS total_volume_per_hour, + SUM(current_bytes_per_hour) AS total_bytes_per_hour, -- service-level throughput - SUM(service_volume_per_hour) AS total_service_volume_per_hour, - SUM(service_cost_per_hour_volume_usd) AS total_service_cost_per_hour + SUM(current_service_events_per_hour) AS total_service_volume_per_hour, + SUM(current_service_volume_usd_per_hour) AS total_service_cost_per_hour FROM datadog_account_statuses_cache; diff --git a/internal/sqlite/queries/log_event_policies.sql b/internal/sqlite/queries/log_event_policies.sql deleted file mode 100644 index c9bffb35..00000000 --- a/internal/sqlite/queries/log_event_policies.sql +++ /dev/null @@ -1,12 +0,0 @@ --- name: CountLogEventPolicies :one -SELECT COUNT(*) FROM log_event_policies; - --- name: ApproveLogEventPolicy :exec -UPDATE log_event_policies -SET approved_at = ?, approved_by = ? -WHERE id = ?; - --- name: DismissLogEventPolicy :exec -UPDATE log_event_policies -SET dismissed_at = ?, dismissed_by = ? -WHERE id = ?; diff --git a/internal/sqlite/queries/log_event_policy_category_statuses.sql b/internal/sqlite/queries/log_event_policy_category_statuses.sql index b5285bf6..f0ad0ef1 100644 --- a/internal/sqlite/queries/log_event_policy_category_statuses.sql +++ b/internal/sqlite/queries/log_event_policy_category_statuses.sql @@ -20,7 +20,7 @@ SELECT CAST(COALESCE(policy_pending_high_count, 0) AS INTEGER) AS policy_pending_high_count, CAST(COALESCE(policy_pending_medium_count, 0) AS INTEGER) AS policy_pending_medium_count, CAST(COALESCE(policy_pending_low_count, 0) AS INTEGER) AS policy_pending_low_count -FROM log_event_policy_category_statuses_cache +FROM recommendation_category_statuses_cache WHERE category IS NOT NULL AND category != '' AND category_type = ?1 ORDER BY estimated_cost_reduction_per_hour_usd DESC NULLS LAST, pending_count DESC; diff --git a/internal/sqlite/queries/log_event_policy_statuses.sql b/internal/sqlite/queries/log_event_policy_statuses.sql index 1c6980c2..87903ec3 100644 --- a/internal/sqlite/queries/log_event_policy_statuses.sql +++ b/internal/sqlite/queries/log_event_policy_statuses.sql @@ -2,33 +2,33 @@ SELECT COALESCE(service_name, '') AS service_name, COALESCE(log_event_name, '') AS log_event_name, - volume_per_hour, - bytes_per_hour, - estimated_cost_reduction_per_hour_usd AS estimated_cost_per_hour, - estimated_cost_reduction_per_hour_bytes_usd AS estimated_cost_per_hour_bytes, - estimated_cost_reduction_per_hour_volume_usd AS estimated_cost_per_hour_volume, - estimated_bytes_reduction_per_hour AS estimated_bytes_per_hour, - estimated_volume_reduction_per_hour AS estimated_volume_per_hour -FROM log_event_policy_statuses_cache + current_events_per_hour AS volume_per_hour, + current_bytes_per_hour AS bytes_per_hour, + impact_total_usd_per_hour AS estimated_cost_per_hour, + impact_bytes_usd_per_hour AS estimated_cost_per_hour_bytes, + impact_volume_usd_per_hour AS estimated_cost_per_hour_volume, + impact_bytes_per_hour AS estimated_bytes_per_hour, + impact_events_per_hour AS estimated_volume_per_hour +FROM recommendation_statuses_cache WHERE category = ?1 AND status = 'PENDING' -ORDER BY estimated_cost_reduction_per_hour_usd DESC, volume_per_hour DESC +ORDER BY impact_total_usd_per_hour DESC, current_events_per_hour DESC LIMIT ?2; -- name: ListPendingPIIPolicies :many SELECT COALESCE(service_name, '') AS service_name, COALESCE(log_event_name, '') AS log_event_name, - COALESCE(lep.analysis, '') AS analysis, - volume_per_hour, + COALESCE(ler.analysis, '') AS analysis, + current_events_per_hour AS volume_per_hour, CAST(COALESCE(( SELECT MAX(CASE json_extract(f.value, '$.observed') WHEN 1 THEN 1 ELSE 0 END) - FROM json_each(json_extract(lep.analysis, '$.pii_leakage.fields')) f + FROM json_each(json_extract(ler.analysis, '$.pii_leakage.fields')) f ), 0) AS INTEGER) AS any_observed -FROM log_event_policy_statuses_cache leps -LEFT JOIN log_event_policies lep ON lep.id = leps.policy_id +FROM recommendation_statuses_cache leps +LEFT JOIN log_event_recommendations ler ON ler.id = leps.recommendation_id WHERE leps.category = 'pii_leakage' AND leps.status = 'PENDING' -ORDER BY any_observed DESC, leps.volume_per_hour DESC; +ORDER BY any_observed DESC, leps.current_events_per_hour DESC; -- name: CountFixedPIIPolicies :one -SELECT CAST(COUNT(*) AS INTEGER) FROM log_event_policy_statuses_cache +SELECT CAST(COUNT(*) AS INTEGER) FROM recommendation_statuses_cache WHERE category = 'pii_leakage' AND status = 'APPROVED'; diff --git a/internal/sqlite/queries/log_event_statuses.sql b/internal/sqlite/queries/log_event_statuses.sql index 5bc309b1..209342ad 100644 --- a/internal/sqlite/queries/log_event_statuses.sql +++ b/internal/sqlite/queries/log_event_statuses.sql @@ -1,11 +1,11 @@ -- name: ListLogEventStatusesByService :many SELECT COALESCE(le.name, '') AS log_event_name, - les.volume_per_hour, - les.bytes_per_hour, - les.cost_per_hour_usd, - CAST(COALESCE(les.pending_policy_count, 0) AS INTEGER) AS pending_policy_count, - CAST(COALESCE(les.approved_policy_count, 0) AS INTEGER) AS approved_policy_count, + les.current_events_per_hour AS volume_per_hour, + les.current_bytes_per_hour AS bytes_per_hour, + les.current_total_usd_per_hour AS cost_per_hour_usd, + CAST(COALESCE(les.pending_recommendation_count, 0) AS INTEGER) AS pending_policy_count, + CAST(COALESCE(les.approved_recommendation_count, 0) AS INTEGER) AS approved_policy_count, CAST(COALESCE(les.policy_pending_critical_count, 0) AS INTEGER) AS policy_pending_critical_count, CAST(COALESCE(les.policy_pending_high_count, 0) AS INTEGER) AS policy_pending_high_count, CAST(COALESCE(les.policy_pending_medium_count, 0) AS INTEGER) AS policy_pending_medium_count, @@ -14,5 +14,5 @@ FROM log_events le JOIN services s ON s.id = le.service_id LEFT JOIN log_event_statuses_cache les ON les.log_event_id = le.id WHERE s.name = ?1 -ORDER BY les.cost_per_hour_usd DESC, les.volume_per_hour DESC +ORDER BY les.current_total_usd_per_hour DESC, les.current_events_per_hour DESC LIMIT ?2; diff --git a/internal/sqlite/queries/policy_cards.sql b/internal/sqlite/queries/policy_cards.sql index 151c63fd..1907516b 100644 --- a/internal/sqlite/queries/policy_cards.sql +++ b/internal/sqlite/queries/policy_cards.sql @@ -1,40 +1,39 @@ -- name: GetPolicyCard :one -- Fetches a single policy with all context needed for rich card rendering. --- Main table: log_event_policy_statuses_cache (denormalized policy + metrics). +-- Main table: recommendation_statuses_cache (denormalized recommendation + metrics). -- JOINs enrich with: category display name, AI analysis, log examples, baselines. SELECT - COALESCE(ps.policy_id, '') AS policy_id, + COALESCE(ps.recommendation_id, '') AS policy_id, COALESCE(ps.service_name, '') AS service_name, COALESCE(ps.log_event_name, '') AS log_event_name, COALESCE(ps.category, '') AS category, COALESCE(ps.category_type, '') AS category_type, COALESCE(ps.action, '') AS "action", COALESCE(ps.status, '') AS status, - ps.volume_per_hour, - ps.bytes_per_hour, - ps.estimated_cost_reduction_per_hour_usd AS estimated_cost_per_hour, - ps.estimated_volume_reduction_per_hour AS estimated_volume_per_hour, - ps.estimated_bytes_reduction_per_hour AS estimated_bytes_per_hour, + ps.current_events_per_hour AS volume_per_hour, + ps.current_bytes_per_hour AS bytes_per_hour, + ps.impact_total_usd_per_hour AS estimated_cost_per_hour, + ps.impact_events_per_hour AS estimated_volume_per_hour, + ps.impact_bytes_per_hour AS estimated_bytes_per_hour, COALESCE(ps.severity, '') AS severity, ps.survival_rate, COALESCE(cat.display_name, '') AS category_display_name, - COALESCE(lep.analysis, '') AS analysis, + COALESCE(ler.analysis, '') AS analysis, COALESCE(le.examples, '') AS examples, le.baseline_avg_bytes AS event_baseline_avg_bytes, le.baseline_volume_per_hour AS event_baseline_volume_per_hour, COALESCE(ps.log_event_id, '') AS log_event_id -FROM log_event_policy_statuses_cache ps -LEFT JOIN log_event_policy_category_statuses_cache cat ON cat.category = ps.category -LEFT JOIN log_event_policies lep ON lep.id = ps.policy_id +FROM recommendation_statuses_cache ps +LEFT JOIN recommendation_category_statuses_cache cat ON cat.category = ps.category +LEFT JOIN log_event_recommendations ler ON ler.id = ps.recommendation_id LEFT JOIN log_events le ON le.id = ps.log_event_id -WHERE ps.policy_id = ?1; +WHERE ps.recommendation_id = ?1; -- name: ListFieldsByLogEvent :many -- Returns per-field metadata for a log event, used to show per-field byte impact -- in quality policies (instrumentation_bloat, oversized_fields, duplicate_fields). SELECT - COALESCE(field_path, '') AS field_path, - baseline_avg_bytes -FROM log_event_fields -WHERE log_event_id = ?1 -ORDER BY baseline_avg_bytes DESC; + '' AS field_path, + CAST(NULL AS REAL) AS baseline_avg_bytes +FROM log_events +WHERE id = ?1 AND 1 = 0; diff --git a/internal/sqlite/queries/service_statuses.sql b/internal/sqlite/queries/service_statuses.sql index 0b82e7a7..fee382ad 100644 --- a/internal/sqlite/queries/service_statuses.sql +++ b/internal/sqlite/queries/service_statuses.sql @@ -4,40 +4,40 @@ SELECT COALESCE(ssc.health, '') AS health, CAST(COALESCE(ssc.log_event_count, 0) AS INTEGER) AS log_event_count, CAST(COALESCE(ssc.log_event_analyzed_count, 0) AS INTEGER) AS log_event_analyzed_count, - CAST(COALESCE(ssc.policy_pending_count, 0) AS INTEGER) AS policy_pending_count, - CAST(COALESCE(ssc.policy_approved_count, 0) AS INTEGER) AS policy_approved_count, - CAST(COALESCE(ssc.policy_dismissed_count, 0) AS INTEGER) AS policy_dismissed_count, + CAST(COALESCE(ssc.pending_recommendation_count, 0) AS INTEGER) AS policy_pending_count, + CAST(COALESCE(ssc.approved_recommendation_count, 0) AS INTEGER) AS policy_approved_count, + CAST(COALESCE(ssc.dismissed_recommendation_count, 0) AS INTEGER) AS policy_dismissed_count, CAST(COALESCE(ssc.policy_pending_critical_count, 0) AS INTEGER) AS policy_pending_critical_count, CAST(COALESCE(ssc.policy_pending_high_count, 0) AS INTEGER) AS policy_pending_high_count, CAST(COALESCE(ssc.policy_pending_medium_count, 0) AS INTEGER) AS policy_pending_medium_count, CAST(COALESCE(ssc.policy_pending_low_count, 0) AS INTEGER) AS policy_pending_low_count, - ssc.service_volume_per_hour, - ssc.service_debug_volume_per_hour, - ssc.service_info_volume_per_hour, - ssc.service_warn_volume_per_hour, - ssc.service_error_volume_per_hour, - ssc.service_other_volume_per_hour, - ssc.service_cost_per_hour_volume_usd, - ssc.log_event_volume_per_hour, - ssc.log_event_bytes_per_hour, - ssc.log_event_cost_per_hour_usd, - ssc.log_event_cost_per_hour_bytes_usd, - ssc.log_event_cost_per_hour_volume_usd, - ssc.estimated_volume_reduction_per_hour, - ssc.estimated_bytes_reduction_per_hour, - ssc.estimated_cost_reduction_per_hour_usd, - ssc.estimated_cost_reduction_per_hour_bytes_usd, - ssc.estimated_cost_reduction_per_hour_volume_usd, - ssc.observed_volume_per_hour_before, - ssc.observed_volume_per_hour_after, - ssc.observed_bytes_per_hour_before, - ssc.observed_bytes_per_hour_after, - ssc.observed_cost_per_hour_before_usd, - ssc.observed_cost_per_hour_before_bytes_usd, - ssc.observed_cost_per_hour_before_volume_usd, - ssc.observed_cost_per_hour_after_usd, - ssc.observed_cost_per_hour_after_bytes_usd, - ssc.observed_cost_per_hour_after_volume_usd + ssc.current_service_events_per_hour AS service_volume_per_hour, + ssc.current_service_debug_events_per_hour AS service_debug_volume_per_hour, + ssc.current_service_info_events_per_hour AS service_info_volume_per_hour, + ssc.current_service_warn_events_per_hour AS service_warn_volume_per_hour, + ssc.current_service_error_events_per_hour AS service_error_volume_per_hour, + ssc.current_service_other_events_per_hour AS service_other_volume_per_hour, + ssc.current_service_volume_usd_per_hour AS service_cost_per_hour_volume_usd, + ssc.current_events_per_hour AS log_event_volume_per_hour, + ssc.current_bytes_per_hour AS log_event_bytes_per_hour, + ssc.current_total_usd_per_hour AS log_event_cost_per_hour_usd, + ssc.current_bytes_usd_per_hour AS log_event_cost_per_hour_bytes_usd, + ssc.current_volume_usd_per_hour AS log_event_cost_per_hour_volume_usd, + ssc.impact_events_per_hour AS estimated_volume_reduction_per_hour, + ssc.impact_bytes_per_hour AS estimated_bytes_reduction_per_hour, + ssc.impact_total_usd_per_hour AS estimated_cost_reduction_per_hour_usd, + ssc.impact_bytes_usd_per_hour AS estimated_cost_reduction_per_hour_bytes_usd, + ssc.impact_volume_usd_per_hour AS estimated_cost_reduction_per_hour_volume_usd, + ssc.current_events_per_hour AS observed_volume_per_hour_before, + CAST((ssc.current_events_per_hour - ssc.impact_events_per_hour) AS REAL) AS observed_volume_per_hour_after, + ssc.current_bytes_per_hour AS observed_bytes_per_hour_before, + CAST((ssc.current_bytes_per_hour - ssc.impact_bytes_per_hour) AS REAL) AS observed_bytes_per_hour_after, + ssc.current_total_usd_per_hour AS observed_cost_per_hour_before_usd, + ssc.current_bytes_usd_per_hour AS observed_cost_per_hour_before_bytes_usd, + ssc.current_volume_usd_per_hour AS observed_cost_per_hour_before_volume_usd, + CAST((ssc.current_total_usd_per_hour - ssc.impact_total_usd_per_hour) AS REAL) AS observed_cost_per_hour_after_usd, + CAST((ssc.current_bytes_usd_per_hour - ssc.impact_bytes_usd_per_hour) AS REAL) AS observed_cost_per_hour_after_bytes_usd, + CAST((ssc.current_volume_usd_per_hour - ssc.impact_volume_usd_per_hour) AS REAL) AS observed_cost_per_hour_after_volume_usd FROM service_statuses_cache ssc JOIN services s ON ssc.service_id = s.id ORDER BY @@ -47,7 +47,7 @@ ORDER BY WHEN 'INACTIVE' THEN 3 ELSE 4 END, - ssc.log_event_cost_per_hour_usd DESC, + ssc.current_total_usd_per_hour DESC, s.name; -- name: ListEnabledServiceStatuses :many @@ -56,40 +56,40 @@ SELECT COALESCE(ssc.health, '') AS health, CAST(COALESCE(ssc.log_event_count, 0) AS INTEGER) AS log_event_count, CAST(COALESCE(ssc.log_event_analyzed_count, 0) AS INTEGER) AS log_event_analyzed_count, - CAST(COALESCE(ssc.policy_pending_count, 0) AS INTEGER) AS policy_pending_count, - CAST(COALESCE(ssc.policy_approved_count, 0) AS INTEGER) AS policy_approved_count, - CAST(COALESCE(ssc.policy_dismissed_count, 0) AS INTEGER) AS policy_dismissed_count, + CAST(COALESCE(ssc.pending_recommendation_count, 0) AS INTEGER) AS policy_pending_count, + CAST(COALESCE(ssc.approved_recommendation_count, 0) AS INTEGER) AS policy_approved_count, + CAST(COALESCE(ssc.dismissed_recommendation_count, 0) AS INTEGER) AS policy_dismissed_count, CAST(COALESCE(ssc.policy_pending_critical_count, 0) AS INTEGER) AS policy_pending_critical_count, CAST(COALESCE(ssc.policy_pending_high_count, 0) AS INTEGER) AS policy_pending_high_count, CAST(COALESCE(ssc.policy_pending_medium_count, 0) AS INTEGER) AS policy_pending_medium_count, CAST(COALESCE(ssc.policy_pending_low_count, 0) AS INTEGER) AS policy_pending_low_count, - ssc.service_volume_per_hour, - ssc.service_debug_volume_per_hour, - ssc.service_info_volume_per_hour, - ssc.service_warn_volume_per_hour, - ssc.service_error_volume_per_hour, - ssc.service_other_volume_per_hour, - ssc.service_cost_per_hour_volume_usd, - ssc.log_event_volume_per_hour, - ssc.log_event_bytes_per_hour, - ssc.log_event_cost_per_hour_usd, - ssc.log_event_cost_per_hour_bytes_usd, - ssc.log_event_cost_per_hour_volume_usd, - ssc.estimated_volume_reduction_per_hour, - ssc.estimated_bytes_reduction_per_hour, - ssc.estimated_cost_reduction_per_hour_usd, - ssc.estimated_cost_reduction_per_hour_bytes_usd, - ssc.estimated_cost_reduction_per_hour_volume_usd, - ssc.observed_volume_per_hour_before, - ssc.observed_volume_per_hour_after, - ssc.observed_bytes_per_hour_before, - ssc.observed_bytes_per_hour_after, - ssc.observed_cost_per_hour_before_usd, - ssc.observed_cost_per_hour_before_bytes_usd, - ssc.observed_cost_per_hour_before_volume_usd, - ssc.observed_cost_per_hour_after_usd, - ssc.observed_cost_per_hour_after_bytes_usd, - ssc.observed_cost_per_hour_after_volume_usd + ssc.current_service_events_per_hour AS service_volume_per_hour, + ssc.current_service_debug_events_per_hour AS service_debug_volume_per_hour, + ssc.current_service_info_events_per_hour AS service_info_volume_per_hour, + ssc.current_service_warn_events_per_hour AS service_warn_volume_per_hour, + ssc.current_service_error_events_per_hour AS service_error_volume_per_hour, + ssc.current_service_other_events_per_hour AS service_other_volume_per_hour, + ssc.current_service_volume_usd_per_hour AS service_cost_per_hour_volume_usd, + ssc.current_events_per_hour AS log_event_volume_per_hour, + ssc.current_bytes_per_hour AS log_event_bytes_per_hour, + ssc.current_total_usd_per_hour AS log_event_cost_per_hour_usd, + ssc.current_bytes_usd_per_hour AS log_event_cost_per_hour_bytes_usd, + ssc.current_volume_usd_per_hour AS log_event_cost_per_hour_volume_usd, + ssc.impact_events_per_hour AS estimated_volume_reduction_per_hour, + ssc.impact_bytes_per_hour AS estimated_bytes_reduction_per_hour, + ssc.impact_total_usd_per_hour AS estimated_cost_reduction_per_hour_usd, + ssc.impact_bytes_usd_per_hour AS estimated_cost_reduction_per_hour_bytes_usd, + ssc.impact_volume_usd_per_hour AS estimated_cost_reduction_per_hour_volume_usd, + ssc.current_events_per_hour AS observed_volume_per_hour_before, + CAST((ssc.current_events_per_hour - ssc.impact_events_per_hour) AS REAL) AS observed_volume_per_hour_after, + ssc.current_bytes_per_hour AS observed_bytes_per_hour_before, + CAST((ssc.current_bytes_per_hour - ssc.impact_bytes_per_hour) AS REAL) AS observed_bytes_per_hour_after, + ssc.current_total_usd_per_hour AS observed_cost_per_hour_before_usd, + ssc.current_bytes_usd_per_hour AS observed_cost_per_hour_before_bytes_usd, + ssc.current_volume_usd_per_hour AS observed_cost_per_hour_before_volume_usd, + CAST((ssc.current_total_usd_per_hour - ssc.impact_total_usd_per_hour) AS REAL) AS observed_cost_per_hour_after_usd, + CAST((ssc.current_bytes_usd_per_hour - ssc.impact_bytes_usd_per_hour) AS REAL) AS observed_cost_per_hour_after_bytes_usd, + CAST((ssc.current_volume_usd_per_hour - ssc.impact_volume_usd_per_hour) AS REAL) AS observed_cost_per_hour_after_volume_usd FROM service_statuses_cache ssc JOIN services s ON ssc.service_id = s.id WHERE ssc.health NOT IN ('DISABLED', 'INACTIVE') @@ -98,6 +98,6 @@ ORDER BY WHEN 'OK' THEN 1 ELSE 2 END, - ssc.log_event_cost_per_hour_usd DESC, + ssc.current_total_usd_per_hour DESC, s.name LIMIT sqlc.arg('row_limit'); diff --git a/internal/sqlite/schema.sql b/internal/sqlite/schema.sql index e287370a..7f52c9b8 100644 --- a/internal/sqlite/schema.sql +++ b/internal/sqlite/schema.sql @@ -24,45 +24,41 @@ CREATE TABLE conversations ( CREATE TABLE datadog_account_statuses_cache ( id TEXT, account_id TEXT, + approved_recommendation_count INTEGER, + current_bytes_per_hour REAL, + current_bytes_usd_per_hour REAL, + current_events_per_hour REAL, + current_service_events_per_hour REAL, + current_service_volume_usd_per_hour REAL, + current_total_usd_per_hour REAL, + current_volume_usd_per_hour REAL, datadog_account_id TEXT, disabled_services INTEGER, - estimated_bytes_reduction_per_hour REAL, - estimated_cost_reduction_per_hour_bytes_usd REAL, - estimated_cost_reduction_per_hour_usd REAL, - estimated_cost_reduction_per_hour_volume_usd REAL, - estimated_volume_reduction_per_hour REAL, + dismissed_recommendation_count INTEGER, + estimated_bytes_per_hour REAL, + estimated_bytes_usd_per_hour REAL, + estimated_events_per_hour REAL, + estimated_total_usd_per_hour REAL, + estimated_volume_usd_per_hour REAL, health TEXT, + impact_bytes_per_hour REAL, + impact_bytes_usd_per_hour REAL, + impact_events_per_hour REAL, + impact_total_usd_per_hour REAL, + impact_volume_usd_per_hour REAL, inactive_services INTEGER, log_active_services INTEGER, log_event_analyzed_count INTEGER, - log_event_bytes_per_hour REAL, - log_event_cost_per_hour_bytes_usd REAL, - log_event_cost_per_hour_usd REAL, - log_event_cost_per_hour_volume_usd REAL, log_event_count INTEGER, - log_event_volume_per_hour REAL, log_service_count INTEGER, - observed_bytes_per_hour_after REAL, - observed_bytes_per_hour_before REAL, - observed_cost_per_hour_after_bytes_usd REAL, - observed_cost_per_hour_after_usd REAL, - observed_cost_per_hour_after_volume_usd REAL, - observed_cost_per_hour_before_bytes_usd REAL, - observed_cost_per_hour_before_usd REAL, - observed_cost_per_hour_before_volume_usd REAL, - observed_volume_per_hour_after REAL, - observed_volume_per_hour_before REAL, ok_services INTEGER, - policy_approved_count INTEGER, - policy_dismissed_count INTEGER, - policy_pending_count INTEGER, + pending_recommendation_count INTEGER, policy_pending_critical_count INTEGER, policy_pending_high_count INTEGER, policy_pending_low_count INTEGER, policy_pending_medium_count INTEGER, ready_for_use INTEGER, - service_cost_per_hour_volume_usd REAL, - service_volume_per_hour REAL + recommendation_count INTEGER ); CREATE TABLE datadog_accounts ( @@ -83,17 +79,7 @@ CREATE TABLE datadog_log_indexes ( name TEXT ); -CREATE TABLE log_event_fields ( - id TEXT, - account_id TEXT, - baseline_avg_bytes REAL, - created_at TEXT, - field_path TEXT, - log_event_id TEXT, - value_distribution TEXT -); - -CREATE TABLE log_event_policies ( +CREATE TABLE log_event_recommendations ( id TEXT, account_id TEXT, action TEXT, @@ -113,7 +99,67 @@ CREATE TABLE log_event_policies ( workspace_id TEXT ); -CREATE TABLE log_event_policy_category_statuses_cache ( +CREATE TABLE log_event_statuses_cache ( + id TEXT, + account_id TEXT, + approved_recommendation_count INTEGER, + current_bytes_per_hour REAL, + current_bytes_usd_per_hour REAL, + current_events_per_hour REAL, + current_total_usd_per_hour REAL, + current_volume_usd_per_hour REAL, + dismissed_recommendation_count INTEGER, + effective_policy_enabled INTEGER, + estimated_bytes_per_hour REAL, + estimated_bytes_usd_per_hour REAL, + estimated_events_per_hour REAL, + estimated_total_usd_per_hour REAL, + estimated_volume_usd_per_hour REAL, + has_been_analyzed INTEGER, + has_volumes INTEGER, + impact_bytes_per_hour REAL, + impact_bytes_usd_per_hour REAL, + impact_events_per_hour REAL, + impact_total_usd_per_hour REAL, + impact_volume_usd_per_hour REAL, + log_event_id TEXT, + pending_recommendation_count INTEGER, + policy_pending_critical_count INTEGER, + policy_pending_high_count INTEGER, + policy_pending_low_count INTEGER, + policy_pending_medium_count INTEGER, + recommendation_count INTEGER, + service_id TEXT +); + +CREATE TABLE log_events ( + id TEXT, + account_id TEXT, + baseline_avg_bytes REAL, + baseline_volume_per_hour REAL, + created_at TEXT, + description TEXT, + event_nature TEXT, + examples TEXT, + matchers TEXT, + name TEXT, + service_id TEXT, + severity TEXT, + signal_purpose TEXT +); + +CREATE TABLE messages ( + id TEXT, + account_id TEXT, + content TEXT, + conversation_id TEXT, + created_at TEXT, + model TEXT, + role TEXT, + stop_reason TEXT +); + +CREATE TABLE recommendation_category_statuses_cache ( id TEXT, account_id TEXT, action TEXT, @@ -139,140 +185,80 @@ CREATE TABLE log_event_policy_category_statuses_cache ( total_event_count INTEGER ); -CREATE TABLE log_event_policy_statuses_cache ( +CREATE TABLE recommendation_statuses_cache ( id TEXT, account_id TEXT, action TEXT, approved_at TEXT, - bytes_per_hour REAL, category TEXT, category_type TEXT, created_at TEXT, + current_bytes_per_hour REAL, + current_bytes_usd_per_hour REAL, + current_events_per_hour REAL, + current_total_usd_per_hour REAL, + current_volume_usd_per_hour REAL, dismissed_at TEXT, - estimated_bytes_reduction_per_hour REAL, - estimated_cost_reduction_per_hour_bytes_usd REAL, - estimated_cost_reduction_per_hour_usd REAL, - estimated_cost_reduction_per_hour_volume_usd REAL, - estimated_volume_reduction_per_hour REAL, + estimated_bytes_per_hour REAL, + estimated_bytes_usd_per_hour REAL, + estimated_events_per_hour REAL, + estimated_total_usd_per_hour REAL, + estimated_volume_usd_per_hour REAL, + impact_bytes_per_hour REAL, + impact_bytes_usd_per_hour REAL, + impact_events_per_hour REAL, + impact_total_usd_per_hour REAL, + impact_volume_usd_per_hour REAL, log_event_id TEXT, log_event_name TEXT, - policy_id TEXT, + recommendation_id TEXT, service_id TEXT, service_name TEXT, severity TEXT, status TEXT, subjective INTEGER, survival_rate REAL, - volume_per_hour REAL, workspace_id TEXT ); -CREATE TABLE log_event_statuses_cache ( - id TEXT, - account_id TEXT, - approved_policy_count INTEGER, - bytes_per_hour REAL, - cost_per_hour_bytes_usd REAL, - cost_per_hour_usd REAL, - cost_per_hour_volume_usd REAL, - dismissed_policy_count INTEGER, - estimated_bytes_reduction_per_hour REAL, - estimated_cost_reduction_per_hour_bytes_usd REAL, - estimated_cost_reduction_per_hour_usd REAL, - estimated_cost_reduction_per_hour_volume_usd REAL, - estimated_volume_reduction_per_hour REAL, - has_been_analyzed INTEGER, - has_volumes INTEGER, - log_event_id TEXT, - observed_bytes_per_hour_after REAL, - observed_bytes_per_hour_before REAL, - observed_cost_per_hour_after_bytes_usd REAL, - observed_cost_per_hour_after_usd REAL, - observed_cost_per_hour_after_volume_usd REAL, - observed_cost_per_hour_before_bytes_usd REAL, - observed_cost_per_hour_before_usd REAL, - observed_cost_per_hour_before_volume_usd REAL, - observed_volume_per_hour_after REAL, - observed_volume_per_hour_before REAL, - pending_policy_count INTEGER, - policy_count INTEGER, - policy_pending_critical_count INTEGER, - policy_pending_high_count INTEGER, - policy_pending_low_count INTEGER, - policy_pending_medium_count INTEGER, - service_id TEXT, - volume_per_hour REAL -); - -CREATE TABLE log_events ( - id TEXT, - account_id TEXT, - baseline_avg_bytes REAL, - baseline_volume_per_hour REAL, - created_at TEXT, - description TEXT, - event_nature TEXT, - examples TEXT, - matchers TEXT, - name TEXT, - service_id TEXT, - severity TEXT, - signal_purpose TEXT -); - -CREATE TABLE messages ( - id TEXT, - account_id TEXT, - content TEXT, - conversation_id TEXT, - created_at TEXT, - model TEXT, - role TEXT, - stop_reason TEXT -); - CREATE TABLE service_statuses_cache ( id TEXT, account_id TEXT, + approved_recommendation_count INTEGER, + current_bytes_per_hour REAL, + current_bytes_usd_per_hour REAL, + current_events_per_hour REAL, + current_service_debug_events_per_hour REAL, + current_service_error_events_per_hour REAL, + current_service_events_per_hour REAL, + current_service_info_events_per_hour REAL, + current_service_other_events_per_hour REAL, + current_service_volume_usd_per_hour REAL, + current_service_warn_events_per_hour REAL, + current_total_usd_per_hour REAL, + current_volume_usd_per_hour REAL, datadog_account_id TEXT, - estimated_bytes_reduction_per_hour REAL, - estimated_cost_reduction_per_hour_bytes_usd REAL, - estimated_cost_reduction_per_hour_usd REAL, - estimated_cost_reduction_per_hour_volume_usd REAL, - estimated_volume_reduction_per_hour REAL, + dismissed_recommendation_count INTEGER, + estimated_bytes_per_hour REAL, + estimated_bytes_usd_per_hour REAL, + estimated_events_per_hour REAL, + estimated_total_usd_per_hour REAL, + estimated_volume_usd_per_hour REAL, health TEXT, + impact_bytes_per_hour REAL, + impact_bytes_usd_per_hour REAL, + impact_events_per_hour REAL, + impact_total_usd_per_hour REAL, + impact_volume_usd_per_hour REAL, log_event_analyzed_count INTEGER, - log_event_bytes_per_hour REAL, - log_event_cost_per_hour_bytes_usd REAL, - log_event_cost_per_hour_usd REAL, - log_event_cost_per_hour_volume_usd REAL, log_event_count INTEGER, - log_event_volume_per_hour REAL, - observed_bytes_per_hour_after REAL, - observed_bytes_per_hour_before REAL, - observed_cost_per_hour_after_bytes_usd REAL, - observed_cost_per_hour_after_usd REAL, - observed_cost_per_hour_after_volume_usd REAL, - observed_cost_per_hour_before_bytes_usd REAL, - observed_cost_per_hour_before_usd REAL, - observed_cost_per_hour_before_volume_usd REAL, - observed_volume_per_hour_after REAL, - observed_volume_per_hour_before REAL, - policy_approved_count INTEGER, - policy_dismissed_count INTEGER, - policy_pending_count INTEGER, + pending_recommendation_count INTEGER, policy_pending_critical_count INTEGER, policy_pending_high_count INTEGER, policy_pending_low_count INTEGER, policy_pending_medium_count INTEGER, - service_cost_per_hour_volume_usd REAL, - service_debug_volume_per_hour REAL, - service_error_volume_per_hour REAL, - service_id TEXT, - service_info_volume_per_hour REAL, - service_other_volume_per_hour REAL, - service_volume_per_hour REAL, - service_warn_volume_per_hour REAL + recommendation_count INTEGER, + service_id TEXT ); CREATE TABLE services ( diff --git a/internal/sqlite/service_statuses.go b/internal/sqlite/service_statuses.go index a76e2ab9..8a754124 100644 --- a/internal/sqlite/service_statuses.go +++ b/internal/sqlite/service_statuses.go @@ -92,14 +92,23 @@ func mapServiceStatus( svcCostVolume *float64, volume, bytes, costUSD, costBytes, costVolume *float64, estVolume, estBytes, estCostUSD, estCostBytes, estCostVolume *float64, - obsVolBefore, obsVolAfter, obsBytesBefore, obsBytesAfter *float64, + obsVolBefore *float64, + obsVolAfter interface{}, + obsBytesBefore *float64, + obsBytesAfter interface{}, obsCostBefore, obsCostBeforeBytes, obsCostBeforeVolume *float64, - obsCostAfter, obsCostAfterBytes, obsCostAfterVolume *float64, + obsCostAfter, obsCostAfterBytes, obsCostAfterVolume interface{}, ) domain.ServiceStatus { name := "" if serviceName != nil { name = *serviceName } + obsVolAfterF := anyToFloatPtr(obsVolAfter) + obsBytesAfterF := anyToFloatPtr(obsBytesAfter) + obsCostAfterF := anyToFloatPtr(obsCostAfter) + obsCostAfterBytesF := anyToFloatPtr(obsCostAfterBytes) + obsCostAfterVolumeF := anyToFloatPtr(obsCostAfterVolume) + return domain.ServiceStatus{ Name: name, Health: domain.ServiceHealth(health), @@ -136,14 +145,22 @@ func mapServiceStatus( EstimatedCostReductionPerHourVolume: estCostVolume, ObservedVolumePerHourBefore: obsVolBefore, - ObservedVolumePerHourAfter: obsVolAfter, + ObservedVolumePerHourAfter: obsVolAfterF, ObservedBytesPerHourBefore: obsBytesBefore, - ObservedBytesPerHourAfter: obsBytesAfter, + ObservedBytesPerHourAfter: obsBytesAfterF, ObservedCostPerHourBeforeUSD: obsCostBefore, ObservedCostPerHourBeforeBytesUSD: obsCostBeforeBytes, ObservedCostPerHourBeforeVolumeUSD: obsCostBeforeVolume, - ObservedCostPerHourAfterUSD: obsCostAfter, - ObservedCostPerHourAfterBytesUSD: obsCostAfterBytes, - ObservedCostPerHourAfterVolumeUSD: obsCostAfterVolume, + ObservedCostPerHourAfterUSD: obsCostAfterF, + ObservedCostPerHourAfterBytesUSD: obsCostAfterBytesF, + ObservedCostPerHourAfterVolumeUSD: obsCostAfterVolumeF, + } +} + +func anyToFloatPtr(v interface{}) *float64 { + f, ok := toFloat64(v) + if !ok { + return nil } + return &f }