from admin_app.core.settings import AdminSettings from shared.contracts import ( PRODUCT_OPERATIONAL_DATASETS, OperationalDatasetContract, OperationalReadGranularity, get_operational_dataset, ) _MATERIALIZATION_STATUS = "contract_defined_pending_snapshot_view" _REFRESH_BEHAVIOR = "manual_refresh_triggers_sync_boundary" _REPORT_SOURCE = "shared_contract_catalog" _SALES_DATASET_KEY = "sales_orders" _SALES_REPORT_METRICS = { "total_orders": {"key": "total_orders", "label": "Pedidos totais", "aggregation": "count", "description": "Quantidade total de pedidos consolidados no periodo."}, "gross_order_value": {"key": "gross_order_value", "label": "Valor bruto negociado", "aggregation": "sum", "description": "Soma do valor negociado dos pedidos incluidos no recorte."}, "active_orders": {"key": "active_orders", "label": "Pedidos ativos", "aggregation": "count_where_status_active", "description": "Quantidade de pedidos ainda em fluxo operacional ativo."}, "cancelled_orders": {"key": "cancelled_orders", "label": "Pedidos cancelados", "aggregation": "count_where_status_cancelled", "description": "Quantidade de pedidos cancelados no recorte selecionado."}, "cancellation_rate": {"key": "cancellation_rate", "label": "Taxa de cancelamento", "aggregation": "ratio", "description": "Relacao entre pedidos cancelados e total de pedidos consolidados."}, "average_ticket": {"key": "average_ticket", "label": "Ticket medio", "aggregation": "avg", "description": "Media do valor negociado por pedido dentro do recorte."}, } _SALES_DIMENSIONS = { "created_at": {"field_name": "created_at", "label": "Periodo de criacao", "description": "Agrupamento temporal da criacao do pedido.", "default_group_by": True}, "updated_at": {"field_name": "updated_at", "label": "Periodo de atualizacao", "description": "Agrupamento temporal da ultima atualizacao do pedido.", "default_group_by": True}, "data_cancelamento": {"field_name": "data_cancelamento", "label": "Periodo de cancelamento", "description": "Agrupamento temporal do cancelamento registrado.", "default_group_by": True}, "status": {"field_name": "status", "label": "Status do pedido", "description": "Separa os pedidos por etapa operacional."}, "modelo_veiculo": {"field_name": "modelo_veiculo", "label": "Modelo do veiculo", "description": "Recorte por modelo comercial negociado."}, "motivo_cancelamento": {"field_name": "motivo_cancelamento", "label": "Motivo do cancelamento", "description": "Separa cancelamentos pelo motivo operacional registrado."}, } _SALES_FILTERS = { "created_at": {"field_name": "created_at", "label": "Periodo", "filter_type": "date_range", "description": "Intervalo de criacao do pedido consolidado.", "required": True}, "updated_at": {"field_name": "updated_at", "label": "Periodo", "filter_type": "date_range", "description": "Intervalo da ultima atualizacao do pedido.", "required": True}, "data_cancelamento": {"field_name": "data_cancelamento", "label": "Periodo", "filter_type": "date_range", "description": "Intervalo em que o cancelamento foi registrado.", "required": True}, "status": {"field_name": "status", "label": "Status", "filter_type": "enum", "description": "Restringe o consolidado para um ou mais status operacionais."}, "modelo_veiculo": {"field_name": "modelo_veiculo", "label": "Modelo do veiculo", "filter_type": "enum", "description": "Filtra pedidos por modelo comercial reservado."}, "motivo_cancelamento": {"field_name": "motivo_cancelamento", "label": "Motivo do cancelamento", "filter_type": "enum", "description": "Restringe o consolidado para um ou mais motivos operacionais."}, } _SALES_REPORTS = ( {"report_key": "orders_volume", "label": "Volume de pedidos", "description": "Acompanha o volume bruto de pedidos por periodo e status operacional.", "default_time_field": "created_at", "default_granularity": OperationalReadGranularity.AGGREGATE, "metric_keys": ("total_orders", "gross_order_value"), "dimension_fields": ("created_at", "status", "modelo_veiculo"), "filter_fields": ("created_at", "status", "modelo_veiculo")}, {"report_key": "active_vs_cancelled", "label": "Pedidos ativos e cancelados", "description": "Compara pedidos em andamento com pedidos cancelados para leitura operacional da conversao.", "default_time_field": "updated_at", "default_granularity": OperationalReadGranularity.AGGREGATE, "metric_keys": ("active_orders", "cancelled_orders", "cancellation_rate"), "dimension_fields": ("updated_at", "status", "modelo_veiculo"), "filter_fields": ("updated_at", "status", "modelo_veiculo")}, {"report_key": "average_ticket", "label": "Ticket medio", "description": "Consolida a evolucao do valor medio negociado por periodo e por modelo.", "default_time_field": "created_at", "default_granularity": OperationalReadGranularity.AGGREGATE, "metric_keys": ("average_ticket", "gross_order_value", "total_orders"), "dimension_fields": ("created_at", "modelo_veiculo", "status"), "filter_fields": ("created_at", "status", "modelo_veiculo")}, {"report_key": "cancellations_by_period", "label": "Cancelamentos por periodo", "description": "Organiza o volume de cancelamentos e seus motivos ao longo do tempo.", "default_time_field": "data_cancelamento", "default_granularity": OperationalReadGranularity.AGGREGATE, "metric_keys": ("cancelled_orders", "cancellation_rate"), "dimension_fields": ("data_cancelamento", "motivo_cancelamento", "modelo_veiculo"), "filter_fields": ("data_cancelamento", "motivo_cancelamento", "modelo_veiculo")}, ) _REVENUE_DATASET_KEY = "rental_payments" _REVENUE_REPORT_METRICS = { "total_payments": {"key": "total_payments", "label": "Pagamentos totais", "aggregation": "count", "description": "Quantidade total de pagamentos liquidados no periodo."}, "collected_amount": {"key": "collected_amount", "label": "Valor arrecadado", "aggregation": "sum", "description": "Soma do valor liquidado dos pagamentos incluidos no recorte."}, "average_payment_amount": {"key": "average_payment_amount", "label": "Valor medio por pagamento", "aggregation": "avg", "description": "Media do valor liquidado por pagamento no recorte selecionado."}, "distinct_contracts": {"key": "distinct_contracts", "label": "Contratos conciliados", "aggregation": "count_distinct", "description": "Quantidade de contratos distintos com pagamento consolidado no periodo."}, } _REVENUE_DIMENSIONS = { "data_pagamento": {"field_name": "data_pagamento", "label": "Periodo do pagamento", "description": "Agrupamento temporal do pagamento liquidado.", "default_group_by": True}, "created_at": {"field_name": "created_at", "label": "Periodo de registro", "description": "Agrupamento temporal do registro do pagamento no read model administrativo.", "default_group_by": True}, "contrato_numero": {"field_name": "contrato_numero", "label": "Contrato", "description": "Recorte por contrato associado ao pagamento."}, "placa": {"field_name": "placa", "label": "Placa", "description": "Recorte por veiculo vinculado ao contrato pago."}, "protocolo": {"field_name": "protocolo", "label": "Protocolo", "description": "Rastreio por protocolo publico do pagamento."}, } _REVENUE_FILTERS = { "data_pagamento": {"field_name": "data_pagamento", "label": "Periodo do pagamento", "filter_type": "date_range", "description": "Intervalo em que o pagamento foi liquidado.", "required": True}, "created_at": {"field_name": "created_at", "label": "Periodo de registro", "filter_type": "date_range", "description": "Intervalo em que o pagamento foi registrado no dataset administrativo.", "required": True}, "contrato_numero": {"field_name": "contrato_numero", "label": "Contrato", "filter_type": "exact_match", "description": "Filtra pagamentos por contrato associado."}, "placa": {"field_name": "placa", "label": "Placa", "filter_type": "exact_match", "description": "Filtra pagamentos pela placa vinculada ao contrato."}, "protocolo": {"field_name": "protocolo", "label": "Protocolo", "filter_type": "exact_match", "description": "Filtra o consolidado por protocolo publico do pagamento."}, } _REVENUE_REPORTS = ( {"report_key": "payments_volume", "label": "Volume de pagamentos", "description": "Acompanha a quantidade de pagamentos liquidados por periodo, contrato e veiculo.", "default_time_field": "data_pagamento", "default_granularity": OperationalReadGranularity.AGGREGATE, "metric_keys": ("total_payments", "distinct_contracts"), "dimension_fields": ("data_pagamento", "contrato_numero", "placa"), "filter_fields": ("data_pagamento", "contrato_numero", "placa")}, {"report_key": "collected_amount", "label": "Arrecadacao por periodo", "description": "Consolida o valor arrecadado por periodo com apoio de contrato e placa para leitura operacional.", "default_time_field": "data_pagamento", "default_granularity": OperationalReadGranularity.AGGREGATE, "metric_keys": ("collected_amount", "average_payment_amount", "total_payments"), "dimension_fields": ("data_pagamento", "contrato_numero", "placa"), "filter_fields": ("data_pagamento", "contrato_numero", "placa")}, {"report_key": "contract_reconciliation", "label": "Pagamentos por contrato", "description": "Organiza pagamentos conciliados por contrato com rastreio por placa e protocolo publico.", "default_time_field": "data_pagamento", "default_granularity": OperationalReadGranularity.AGGREGATE, "metric_keys": ("collected_amount", "total_payments"), "dimension_fields": ("contrato_numero", "placa", "protocolo"), "filter_fields": ("data_pagamento", "contrato_numero", "placa", "protocolo")}, ) _RENTAL_FLEET_DATASET_KEY = "rental_fleet" _RENTAL_CONTRACTS_DATASET_KEY = "rental_contracts" _RENTAL_REPORT_METRICS = { "total_fleet_vehicles": {"key": "total_fleet_vehicles", "label": "Veiculos da frota", "aggregation": "count", "description": "Quantidade total de veiculos consolidados na frota administrativa."}, "available_fleet_vehicles": {"key": "available_fleet_vehicles", "label": "Veiculos disponiveis", "aggregation": "count_where_status_available", "description": "Quantidade de veiculos em status operacional disponivel para locacao."}, "average_daily_rate": {"key": "average_daily_rate", "label": "Diaria media", "aggregation": "avg", "description": "Media do valor de diaria vigente dos veiculos incluidos no recorte."}, "total_contracts": {"key": "total_contracts", "label": "Contratos totais", "aggregation": "count", "description": "Quantidade total de contratos consolidados no periodo selecionado."}, "active_contracts": {"key": "active_contracts", "label": "Contratos ativos", "aggregation": "count_where_status_active", "description": "Quantidade de contratos ainda em curso no recorte operacional."}, "closed_contracts": {"key": "closed_contracts", "label": "Contratos encerrados", "aggregation": "count_where_status_closed", "description": "Quantidade de contratos concluidos ou encerrados no recorte selecionado."}, "overdue_contracts": {"key": "overdue_contracts", "label": "Devolucoes em atraso", "aggregation": "count_overdue", "description": "Quantidade de contratos com fim previsto vencido e sem devolucao consolidada."}, "occupied_vehicles": {"key": "occupied_vehicles", "label": "Veiculos ocupados", "aggregation": "count_distinct_active_vehicles", "description": "Quantidade de veiculos distintos associados a contratos ativos no periodo."}, "projected_revenue": {"key": "projected_revenue", "label": "Receita prevista", "aggregation": "sum", "description": "Soma do valor previsto dos contratos incluidos no recorte."}, "final_revenue": {"key": "final_revenue", "label": "Receita final", "aggregation": "sum", "description": "Soma do valor final consolidado dos contratos no recorte selecionado."}, "revenue_delta": {"key": "revenue_delta", "label": "Desvio entre previsto e final", "aggregation": "difference", "description": "Diferenca consolidada entre receita prevista e receita final dos contratos."}, } _RENTAL_DIMENSIONS = { "created_at": {"field_name": "created_at", "label": "Periodo de cadastro", "description": "Agrupamento temporal do cadastro no read model administrativo.", "default_group_by": True}, "categoria": {"field_name": "categoria", "label": "Categoria", "description": "Recorte por categoria comercial da locacao."}, "status": {"field_name": "status", "label": "Status", "description": "Separa frota ou contratos por status operacional."}, "modelo": {"field_name": "modelo", "label": "Modelo", "description": "Recorte por modelo do veiculo de locacao."}, "placa": {"field_name": "placa", "label": "Placa", "description": "Rastreio por placa do veiculo locado."}, "data_inicio": {"field_name": "data_inicio", "label": "Inicio da locacao", "description": "Agrupamento temporal da abertura do contrato.", "default_group_by": True}, "data_fim_prevista": {"field_name": "data_fim_prevista", "label": "Fim previsto", "description": "Agrupamento temporal do fim previsto da locacao.", "default_group_by": True}, "data_devolucao": {"field_name": "data_devolucao", "label": "Data de devolucao", "description": "Agrupamento temporal da devolucao consolidada do contrato.", "default_group_by": True}, "updated_at": {"field_name": "updated_at", "label": "Ultima atualizacao", "description": "Agrupamento temporal da ultima atualizacao do contrato.", "default_group_by": True}, "modelo_veiculo": {"field_name": "modelo_veiculo", "label": "Modelo do veiculo", "description": "Recorte por modelo do veiculo vinculado ao contrato."}, "contrato_numero": {"field_name": "contrato_numero", "label": "Contrato", "description": "Rastreio por numero publico do contrato."}, } _RENTAL_FILTERS = { "created_at": {"field_name": "created_at", "label": "Periodo de cadastro", "filter_type": "date_range", "description": "Intervalo de cadastro no dataset administrativo.", "required": True}, "categoria": {"field_name": "categoria", "label": "Categoria", "filter_type": "enum", "description": "Filtra frota ou contratos por categoria comercial."}, "status": {"field_name": "status", "label": "Status", "filter_type": "enum", "description": "Restringe o consolidado para um ou mais status operacionais."}, "modelo": {"field_name": "modelo", "label": "Modelo", "filter_type": "enum", "description": "Filtra o consolidado por modelo da frota."}, "placa": {"field_name": "placa", "label": "Placa", "filter_type": "exact_match", "description": "Filtra o consolidado pela placa do veiculo."}, "data_inicio": {"field_name": "data_inicio", "label": "Inicio da locacao", "filter_type": "date_range", "description": "Intervalo de abertura dos contratos de locacao.", "required": True}, "data_fim_prevista": {"field_name": "data_fim_prevista", "label": "Fim previsto", "filter_type": "date_range", "description": "Intervalo do fim previsto dos contratos de locacao.", "required": True}, "updated_at": {"field_name": "updated_at", "label": "Ultima atualizacao", "filter_type": "date_range", "description": "Intervalo da ultima atualizacao operacional do contrato.", "required": True}, "modelo_veiculo": {"field_name": "modelo_veiculo", "label": "Modelo do veiculo", "filter_type": "enum", "description": "Filtra contratos pelo modelo do veiculo locado."}, "contrato_numero": {"field_name": "contrato_numero", "label": "Contrato", "filter_type": "exact_match", "description": "Filtra o consolidado por numero publico do contrato."}, } _RENTAL_REPORTS = ( {"report_key": "fleet_availability", "label": "Disponibilidade da frota", "description": "Resume disponibilidade, status e diaria vigente da frota de locacao.", "dataset_key": _RENTAL_FLEET_DATASET_KEY, "default_time_field": "created_at", "default_granularity": OperationalReadGranularity.AGGREGATE, "metric_keys": ("total_fleet_vehicles", "available_fleet_vehicles", "average_daily_rate"), "dimension_fields": ("created_at", "categoria", "status", "modelo"), "filter_fields": ("created_at", "categoria", "status", "modelo", "placa")}, {"report_key": "contracts_lifecycle", "label": "Contratos ativos e encerrados", "description": "Organiza o ciclo operacional dos contratos de locacao entre abertos, ativos e encerrados.", "dataset_key": _RENTAL_CONTRACTS_DATASET_KEY, "default_time_field": "data_inicio", "default_granularity": OperationalReadGranularity.AGGREGATE, "metric_keys": ("total_contracts", "active_contracts", "closed_contracts"), "dimension_fields": ("data_inicio", "categoria", "status", "modelo_veiculo"), "filter_fields": ("data_inicio", "categoria", "status", "placa", "contrato_numero")}, {"report_key": "overdue_returns", "label": "Devolucoes em atraso", "description": "Acompanha contratos com fim previsto vencido e sem devolucao consolidada.", "dataset_key": _RENTAL_CONTRACTS_DATASET_KEY, "default_time_field": "data_fim_prevista", "default_granularity": OperationalReadGranularity.AGGREGATE, "metric_keys": ("overdue_contracts", "active_contracts"), "dimension_fields": ("data_fim_prevista", "categoria", "status", "placa"), "filter_fields": ("data_fim_prevista", "categoria", "status", "placa", "contrato_numero")}, {"report_key": "fleet_occupancy", "label": "Ocupacao da frota", "description": "Consolida o uso da frota por contratos ativos ao longo do tempo e por categoria.", "dataset_key": _RENTAL_CONTRACTS_DATASET_KEY, "default_time_field": "data_inicio", "default_granularity": OperationalReadGranularity.AGGREGATE, "metric_keys": ("occupied_vehicles", "active_contracts", "projected_revenue"), "dimension_fields": ("data_inicio", "categoria", "modelo_veiculo", "status"), "filter_fields": ("data_inicio", "categoria", "status", "modelo_veiculo", "placa")}, {"report_key": "projected_vs_final_revenue", "label": "Receita prevista versus final", "description": "Compara o valor previsto na abertura do contrato com o valor final consolidado da locacao.", "dataset_key": _RENTAL_CONTRACTS_DATASET_KEY, "default_time_field": "updated_at", "default_granularity": OperationalReadGranularity.AGGREGATE, "metric_keys": ("projected_revenue", "final_revenue", "revenue_delta"), "dimension_fields": ("updated_at", "categoria", "status", "modelo_veiculo"), "filter_fields": ("updated_at", "categoria", "status", "placa", "contrato_numero")}, ) _BOT_FLOW_DATASET_KEY = "conversation_turns" _BOT_FLOW_REPORT_METRICS = { "total_turns": {"key": "total_turns", "label": "Turnos totais", "aggregation": "count", "description": "Quantidade total de turnos processados no recorte operacional."}, "completed_turns": {"key": "completed_turns", "label": "Turnos concluidos", "aggregation": "count_where_status_completed", "description": "Quantidade de turnos concluidos pelo fluxo operacional do bot."}, "errored_turns": {"key": "errored_turns", "label": "Turnos com falha", "aggregation": "count_where_status_error", "description": "Quantidade de turnos com falha operacional no processamento."}, "tool_routed_turns": {"key": "tool_routed_turns", "label": "Turnos com tool", "aggregation": "count_where_tool_called", "description": "Quantidade de turnos que acionaram pelo menos uma tool no fluxo."}, "fallback_turns": {"key": "fallback_turns", "label": "Turnos em fallback", "aggregation": "count_where_action_fallback", "description": "Quantidade de turnos encaminhados para fallback funcional do bot."}, "handoff_turns": {"key": "handoff_turns", "label": "Turnos em handoff", "aggregation": "count_where_action_handoff", "description": "Quantidade de turnos que escalaram para handoff humano."}, } _BOT_FLOW_DIMENSIONS = { "started_at": {"field_name": "started_at", "label": "Inicio do turno", "description": "Agrupamento temporal do inicio do processamento do turno.", "default_group_by": True}, "completed_at": {"field_name": "completed_at", "label": "Fim do turno", "description": "Agrupamento temporal da finalizacao do turno processado.", "default_group_by": True}, "channel": {"field_name": "channel", "label": "Canal", "description": "Recorte por canal operacional do atendimento."}, "turn_status": {"field_name": "turn_status", "label": "Status do turno", "description": "Separa o fluxo pelos estados operacionais do turno."}, "action": {"field_name": "action", "label": "Acao do fluxo", "description": "Recorte pela acao tomada pelo orquestrador durante o turno."}, "tool_name": {"field_name": "tool_name", "label": "Tool acionada", "description": "Rastreio da tool utilizada durante o turno do bot."}, "domain": {"field_name": "domain", "label": "Dominio operacional", "description": "Recorte pelo dominio operacional associado ao turno."}, "intent": {"field_name": "intent", "label": "Intencao", "description": "Recorte pela intencao classificada para o turno."}, } _BOT_FLOW_FILTERS = { "started_at": {"field_name": "started_at", "label": "Inicio do turno", "filter_type": "date_range", "description": "Intervalo de inicio do processamento do turno.", "required": True}, "completed_at": {"field_name": "completed_at", "label": "Fim do turno", "filter_type": "date_range", "description": "Intervalo de finalizacao do turno processado."}, "channel": {"field_name": "channel", "label": "Canal", "filter_type": "enum", "description": "Filtra o fluxo por canal operacional."}, "turn_status": {"field_name": "turn_status", "label": "Status do turno", "filter_type": "enum", "description": "Restringe o consolidado para um ou mais status do turno."}, "action": {"field_name": "action", "label": "Acao do fluxo", "filter_type": "enum", "description": "Restringe o consolidado para uma ou mais acoes do fluxo do bot."}, "tool_name": {"field_name": "tool_name", "label": "Tool acionada", "filter_type": "enum", "description": "Filtra os turnos pela tool utilizada no atendimento."}, "domain": {"field_name": "domain", "label": "Dominio operacional", "filter_type": "enum", "description": "Filtra o fluxo pelo dominio operacional associado ao turno."}, "intent": {"field_name": "intent", "label": "Intencao", "filter_type": "enum", "description": "Filtra o consolidado pela intencao classificada para o turno."}, } _BOT_FLOW_REPORTS = ( {"report_key": "turn_status_overview", "label": "Status dos turnos", "description": "Acompanha o andamento operacional dos turnos por status, canal e dominio.", "default_time_field": "started_at", "default_granularity": OperationalReadGranularity.AGGREGATE, "metric_keys": ("total_turns", "completed_turns", "errored_turns"), "dimension_fields": ("started_at", "turn_status", "channel", "domain"), "filter_fields": ("started_at", "turn_status", "channel", "domain")}, {"report_key": "action_routing_flow", "label": "Roteamento do fluxo", "description": "Organiza as acoes do orquestrador entre resposta, fallback, handoff e outros caminhos operacionais.", "default_time_field": "started_at", "default_granularity": OperationalReadGranularity.AGGREGATE, "metric_keys": ("total_turns", "fallback_turns", "handoff_turns"), "dimension_fields": ("started_at", "action", "channel", "domain"), "filter_fields": ("started_at", "action", "channel", "domain", "intent")}, {"report_key": "tool_activation_flow", "label": "Uso operacional de tools", "description": "Mostra quais turnos acionaram tools e como isso se distribui no fluxo do bot.", "default_time_field": "started_at", "default_granularity": OperationalReadGranularity.AGGREGATE, "metric_keys": ("tool_routed_turns", "completed_turns", "errored_turns"), "dimension_fields": ("started_at", "tool_name", "action", "domain"), "filter_fields": ("started_at", "tool_name", "action", "domain", "intent")}, {"report_key": "fallback_and_handoff", "label": "Fallback e handoff", "description": "Destaca turnos que saem do fluxo padrao para fallback funcional ou handoff humano.", "default_time_field": "started_at", "default_granularity": OperationalReadGranularity.AGGREGATE, "metric_keys": ("fallback_turns", "handoff_turns", "errored_turns"), "dimension_fields": ("started_at", "action", "channel", "intent"), "filter_fields": ("started_at", "action", "channel", "intent", "domain")}, {"report_key": "operational_failures", "label": "Falhas operacionais do fluxo", "description": "Ajuda a triar turnos com falha por status, acao e canal operacional.", "default_time_field": "started_at", "default_granularity": OperationalReadGranularity.AGGREGATE, "metric_keys": ("errored_turns", "total_turns", "tool_routed_turns"), "dimension_fields": ("started_at", "turn_status", "action", "channel"), "filter_fields": ("started_at", "turn_status", "action", "channel", "tool_name")}, ) _CONVERSATION_TELEMETRY_DATASET_KEY = "conversation_turns" _CONVERSATION_TELEMETRY_REPORT_METRICS = { "total_turns": {"key": "total_turns", "label": "Turnos totais", "aggregation": "count", "description": "Quantidade total de turnos observados no recorte de telemetria."}, "distinct_conversations": {"key": "distinct_conversations", "label": "Conversas distintas", "aggregation": "count_distinct", "description": "Quantidade de conversas distintas observadas no recorte selecionado."}, "average_latency_ms": {"key": "average_latency_ms", "label": "Latencia media", "aggregation": "avg", "description": "Media do tempo de processamento do turno em milissegundos."}, "p95_latency_ms": {"key": "p95_latency_ms", "label": "Latencia p95", "aggregation": "percentile_p95", "description": "Percentil 95 do tempo de processamento dos turnos observados."}, "tool_routed_turns": {"key": "tool_routed_turns", "label": "Turnos com tool", "aggregation": "count_where_tool_called", "description": "Quantidade de turnos que acionaram pelo menos uma tool no atendimento."}, "errored_turns": {"key": "errored_turns", "label": "Turnos com falha", "aggregation": "count_where_status_error", "description": "Quantidade de turnos com falha no recorte de telemetria."}, } _CONVERSATION_TELEMETRY_DIMENSIONS = { "started_at": {"field_name": "started_at", "label": "Inicio do turno", "description": "Agrupamento temporal do inicio do processamento do turno.", "default_group_by": True}, "completed_at": {"field_name": "completed_at", "label": "Fim do turno", "description": "Agrupamento temporal da finalizacao do turno.", "default_group_by": True}, "channel": {"field_name": "channel", "label": "Canal", "description": "Recorte por canal operacional do atendimento."}, "domain": {"field_name": "domain", "label": "Dominio operacional", "description": "Recorte pelo dominio operacional associado ao turno."}, "intent": {"field_name": "intent", "label": "Intencao", "description": "Recorte pela intencao classificada para o turno."}, "tool_name": {"field_name": "tool_name", "label": "Tool acionada", "description": "Rastreio da tool utilizada durante o turno."}, "turn_status": {"field_name": "turn_status", "label": "Status do turno", "description": "Separa a telemetria pelos estados observados do turno."}, "action": {"field_name": "action", "label": "Acao do turno", "description": "Recorte pela acao operacional tomada pelo orquestrador."}, } _CONVERSATION_TELEMETRY_FILTERS = { "started_at": {"field_name": "started_at", "label": "Inicio do turno", "filter_type": "date_range", "description": "Intervalo de inicio do processamento do turno.", "required": True}, "completed_at": {"field_name": "completed_at", "label": "Fim do turno", "filter_type": "date_range", "description": "Intervalo de finalizacao do turno processado."}, "channel": {"field_name": "channel", "label": "Canal", "filter_type": "enum", "description": "Filtra a telemetria por canal operacional."}, "domain": {"field_name": "domain", "label": "Dominio operacional", "filter_type": "enum", "description": "Filtra a telemetria pelo dominio associado ao turno."}, "intent": {"field_name": "intent", "label": "Intencao", "filter_type": "enum", "description": "Filtra o recorte pela intencao classificada."}, "tool_name": {"field_name": "tool_name", "label": "Tool acionada", "filter_type": "enum", "description": "Filtra os turnos pela tool utilizada durante o atendimento."}, "turn_status": {"field_name": "turn_status", "label": "Status do turno", "filter_type": "enum", "description": "Restringe o consolidado para um ou mais status observados."}, "action": {"field_name": "action", "label": "Acao do turno", "filter_type": "enum", "description": "Restringe o consolidado para uma ou mais acoes do orquestrador."}, } _CONVERSATION_TELEMETRY_REPORTS = ( {"report_key": "conversation_volume", "label": "Volume de atendimento", "description": "Consolida o volume de turnos e conversas por periodo, canal e dominio.", "default_time_field": "started_at", "default_granularity": OperationalReadGranularity.AGGREGATE, "metric_keys": ("total_turns", "distinct_conversations"), "dimension_fields": ("started_at", "channel", "domain", "intent"), "filter_fields": ("started_at", "channel", "domain", "intent")}, {"report_key": "latency_profile", "label": "Perfil de latencia", "description": "Organiza sinais de latencia media e p95 por canal, dominio e intencao.", "default_time_field": "completed_at", "default_granularity": OperationalReadGranularity.AGGREGATE, "metric_keys": ("average_latency_ms", "p95_latency_ms", "total_turns"), "dimension_fields": ("completed_at", "channel", "domain", "intent"), "filter_fields": ("started_at", "completed_at", "channel", "domain", "intent")}, {"report_key": "domain_distribution", "label": "Distribuicao por dominio", "description": "Mostra como o atendimento se distribui entre dominios, intencoes e canais.", "default_time_field": "started_at", "default_granularity": OperationalReadGranularity.AGGREGATE, "metric_keys": ("total_turns", "distinct_conversations"), "dimension_fields": ("started_at", "domain", "intent", "channel"), "filter_fields": ("started_at", "domain", "intent", "channel")}, {"report_key": "tool_usage_telemetry", "label": "Uso de tools", "description": "Expoe quais tools aparecem com mais frequencia no atendimento e em quais contextos.", "default_time_field": "started_at", "default_granularity": OperationalReadGranularity.AGGREGATE, "metric_keys": ("tool_routed_turns", "total_turns", "errored_turns"), "dimension_fields": ("started_at", "tool_name", "domain", "channel"), "filter_fields": ("started_at", "tool_name", "domain", "channel", "intent")}, {"report_key": "turn_health_status", "label": "Saude por status", "description": "Acompanha estados de saude do atendimento por status observado e acao tomada.", "default_time_field": "started_at", "default_granularity": OperationalReadGranularity.AGGREGATE, "metric_keys": ("errored_turns", "total_turns", "average_latency_ms"), "dimension_fields": ("started_at", "turn_status", "action", "channel"), "filter_fields": ("started_at", "turn_status", "action", "channel", "domain")}, ) _REPORT_FAMILIES = ( { "key": "sales", "label": "Vendas", "description": "Pedidos, conversao comercial e cancelamentos usados pela operacao interna.", "dataset_keys": ["sales_orders"], }, { "key": "arrecadacao", "label": "Arrecadacao", "description": "Recebimentos de locacao e conciliacao operacional do faturamento.", "dataset_keys": ["rental_payments"], }, { "key": "operacao", "label": "Operacao", "description": "Estoque, revisoes, frota e contratos que suportam o acompanhamento do dia a dia.", "dataset_keys": [ "vehicle_inventory", "review_schedules", "rental_fleet", "rental_contracts", ], }, { "key": "telemetria_atendimento", "label": "Telemetria de atendimento", "description": "Turnos conversacionais, uso de tools e sinais de eficiencia do bot.", "dataset_keys": ["conversation_turns"], }, { "key": "integration_deliveries", "label": "Entregas de integracao", "description": "Rastreio operacional das entregas para provedores e falhas de despacho.", "dataset_keys": ["integration_deliveries"], }, ) class ReportService: def __init__(self, settings: AdminSettings): self.settings = settings def build_overview_payload(self) -> dict: datasets = PRODUCT_OPERATIONAL_DATASETS near_real_time_count = sum(1 for dataset in datasets if dataset.freshness_target.value == "near_real_time") intra_hour_count = sum(1 for dataset in datasets if dataset.freshness_target.value == "intra_hour") return { "mode": "shared_contract_bootstrap", "metrics": [ { "key": "datasets", "label": "Datasets liberados", "value": str(len(datasets)), "description": "Datasets operacionais explicitamente liberados para relatorios administrativos.", }, { "key": "domains", "label": "Dominios operacionais", "value": str(len({dataset.domain for dataset in datasets})), "description": "Dominios cobertos pelo catalogo inicial de leitura administrativa.", }, { "key": "near_real_time_targets", "label": "Metas near real time", "value": str(near_real_time_count), "description": "Datasets cuja UX espera consolidacao mais frequente sem leitura live do produto.", }, { "key": "intra_hour_targets", "label": "Metas intra-hour", "value": str(intra_hour_count), "description": "Datasets de apoio operacional e telemetria servidos por consolidacao eventual intra-horaria.", }, ], "materialization": self._build_materialization_payload(), "report_families": list(_REPORT_FAMILIES), "next_steps": [ "Criar snapshots sanitizados no admin para vendas, arrecadacao e operacao.", "Servir views dedicadas por caso de uso em vez de espelhar o schema operacional do produto.", "Exibir carimbo de atualizacao e watermark quando a camada de sincronizacao entrar em producao.", ], } def list_datasets_payload(self) -> dict: return { "source": _REPORT_SOURCE, "materialization": self._build_materialization_payload(), "datasets": [ self._serialize_dataset_summary(dataset) for dataset in sorted( PRODUCT_OPERATIONAL_DATASETS, key=lambda item: (item.domain.value, item.dataset_key), ) ], } def get_dataset_payload(self, dataset_key: str) -> dict | None: dataset = get_operational_dataset(dataset_key) if dataset is None: return None return { "source": _REPORT_SOURCE, "materialization": self._build_materialization_payload(dataset), "dataset": self._serialize_dataset_detail(dataset), } def build_sales_overview_payload(self) -> dict: dataset = self._get_sales_dataset() return { "domain": dataset.domain, "mode": "sales_contract_bootstrap", "source_dataset_keys": [dataset.dataset_key], "metrics": [ { "key": "source_datasets", "label": "Datasets fonte", "value": "1", "description": "A estrutura inicial de vendas nasce apoiada em um dataset sanitizado de pedidos.", }, { "key": "initial_reports", "label": "Relatorios iniciais", "value": str(len(_SALES_REPORTS)), "description": "Casos de uso de vendas previstos para a primeira superficie administrativa do dominio.", }, { "key": "allowed_fields", "label": "Campos liberados", "value": str(len(dataset.allowed_fields)), "description": "Campos operacionais expostos para agregacao e filtros de vendas.", }, { "key": "blocked_fields", "label": "Campos bloqueados", "value": str(len(dataset.blocked_fields)), "description": "Campos sensiveis que permanecem fora do read model administrativo.", }, { "key": "freshness_target", "label": "Meta de frescor", "value": dataset.freshness_target.value, "description": "Objetivo inicial de consolidacao para a UX dos relatorios de vendas.", }, ], "materialization": self._build_materialization_payload(dataset), "reports": [self._serialize_sales_report_summary(report) for report in _SALES_REPORTS], "next_steps": [ "Materializar snapshot sanitizado de sales_orders no banco administrativo.", "Criar dedicated views separadas para volume, ticket medio e cancelamentos.", "Exibir watermark e timestamp da ultima consolidacao quando o ETL incremental entrar em producao.", ], } def list_sales_reports_payload(self) -> dict: dataset = self._get_sales_dataset() return { "domain": dataset.domain, "source": _REPORT_SOURCE, "materialization": self._build_materialization_payload(dataset), "reports": [self._serialize_sales_report_summary(report) for report in _SALES_REPORTS], } def get_sales_report_payload(self, report_key: str) -> dict | None: normalized_report_key = self._normalize_key(report_key) dataset = self._get_sales_dataset() for report in _SALES_REPORTS: if report["report_key"] == normalized_report_key: return { "domain": dataset.domain, "source": _REPORT_SOURCE, "materialization": self._build_materialization_payload(dataset), "report": self._serialize_sales_report_detail(report, dataset), } return None def build_revenue_overview_payload(self) -> dict: dataset = self._get_revenue_dataset() return { "area": "arrecadacao", "source_domain": dataset.domain, "mode": "revenue_contract_bootstrap", "source_dataset_keys": [dataset.dataset_key], "metrics": [ { "key": "source_datasets", "label": "Datasets fonte", "value": "1", "description": "A estrutura inicial de arrecadacao nasce apoiada em um dataset sanitizado de pagamentos.", }, { "key": "initial_reports", "label": "Relatorios iniciais", "value": str(len(_REVENUE_REPORTS)), "description": "Casos de uso iniciais de arrecadacao previstos para a primeira superficie administrativa.", }, { "key": "allowed_fields", "label": "Campos liberados", "value": str(len(dataset.allowed_fields)), "description": "Campos operacionais expostos para agregacao e conciliacao de pagamentos.", }, { "key": "blocked_fields", "label": "Campos bloqueados", "value": str(len(dataset.blocked_fields)), "description": "Campos sensiveis que permanecem fora do read model administrativo.", }, { "key": "freshness_target", "label": "Meta de frescor", "value": dataset.freshness_target.value, "description": "Objetivo inicial de consolidacao para a UX dos relatorios de arrecadacao.", }, ], "materialization": self._build_materialization_payload(dataset), "reports": [self._serialize_revenue_report_summary(report) for report in _REVENUE_REPORTS], "next_steps": [ "Materializar snapshot sanitizado de rental_payments no banco administrativo.", "Criar dedicated views separadas para arrecadacao por periodo e conciliacao por contrato.", "Cruzar contratos e pagamentos em uma etapa futura para abrir inadimplencia operacional sem leitura live do produto.", ], } def list_revenue_reports_payload(self) -> dict: dataset = self._get_revenue_dataset() return { "area": "arrecadacao", "source_domain": dataset.domain, "source": _REPORT_SOURCE, "materialization": self._build_materialization_payload(dataset), "reports": [self._serialize_revenue_report_summary(report) for report in _REVENUE_REPORTS], } def get_revenue_report_payload(self, report_key: str) -> dict | None: normalized_report_key = self._normalize_key(report_key) dataset = self._get_revenue_dataset() for report in _REVENUE_REPORTS: if report["report_key"] == normalized_report_key: return { "area": "arrecadacao", "source_domain": dataset.domain, "source": _REPORT_SOURCE, "materialization": self._build_materialization_payload(dataset), "report": self._serialize_revenue_report_detail(report, dataset), } return None def build_rental_overview_payload(self) -> dict: fleet_dataset = self._get_rental_fleet_dataset() contracts_dataset = self._get_rental_contracts_dataset() return { "area": "locacao", "source_domain": contracts_dataset.domain, "mode": "rental_contract_bootstrap", "source_dataset_keys": [fleet_dataset.dataset_key, contracts_dataset.dataset_key], "metrics": [ { "key": "source_datasets", "label": "Datasets fonte", "value": "2", "description": "A estrutura inicial de locacao nasce sobre snapshots sanitizados de frota e contratos.", }, { "key": "initial_reports", "label": "Relatorios iniciais", "value": str(len(_RENTAL_REPORTS)), "description": "Casos de uso operacionais de locacao previstos para a primeira superficie administrativa.", }, { "key": "fleet_allowed_fields", "label": "Campos liberados da frota", "value": str(len(fleet_dataset.allowed_fields)), "description": "Campos expostos para disponibilidade, categoria e diaria vigente da frota.", }, { "key": "contracts_allowed_fields", "label": "Campos liberados dos contratos", "value": str(len(contracts_dataset.allowed_fields)), "description": "Campos expostos para ciclo do contrato, ocupacao e devolucao operacional.", }, { "key": "freshness_target", "label": "Meta de frescor", "value": contracts_dataset.freshness_target.value, "description": "Objetivo inicial de consolidacao para a UX dos relatorios de locacao.", }, ], "materialization": self._build_materialization_payload(contracts_dataset), "reports": [self._serialize_rental_report_summary(report) for report in _RENTAL_REPORTS], "next_steps": [ "Materializar snapshots sanitizados de rental_fleet e rental_contracts no banco administrativo.", "Criar dedicated views separadas para disponibilidade da frota, contratos em curso e devolucoes em atraso.", "Combinar frota e contratos em uma camada futura de ocupacao sem consultar tabelas live do produto.", ], } def list_rental_reports_payload(self) -> dict: contracts_dataset = self._get_rental_contracts_dataset() return { "area": "locacao", "source_domain": contracts_dataset.domain, "source": _REPORT_SOURCE, "materialization": self._build_materialization_payload(contracts_dataset), "reports": [self._serialize_rental_report_summary(report) for report in _RENTAL_REPORTS], } def get_rental_report_payload(self, report_key: str) -> dict | None: normalized_report_key = self._normalize_key(report_key) for report in _RENTAL_REPORTS: if report["report_key"] == normalized_report_key: dataset = self._get_rental_dataset(report["dataset_key"]) return { "area": "locacao", "source_domain": dataset.domain, "source": _REPORT_SOURCE, "materialization": self._build_materialization_payload(dataset), "report": self._serialize_rental_report_detail(report, dataset), } return None def build_bot_flow_overview_payload(self) -> dict: dataset = self._get_bot_flow_dataset() return { "area": "fluxo_bot", "source_domain": dataset.domain, "mode": "bot_flow_contract_bootstrap", "source_dataset_keys": [dataset.dataset_key], "metrics": [ { "key": "source_datasets", "label": "Datasets fonte", "value": "1", "description": "A estrutura inicial do fluxo do bot nasce apoiada em um dataset sanitizado de turnos operacionais.", }, { "key": "initial_reports", "label": "Relatorios iniciais", "value": str(len(_BOT_FLOW_REPORTS)), "description": "Casos de uso de operacao do fluxo do bot previstos para a primeira superficie administrativa.", }, { "key": "allowed_fields", "label": "Campos liberados", "value": str(len(dataset.allowed_fields)), "description": "Campos operacionais expostos para triagem de status, acao e uso de tools.", }, { "key": "blocked_fields", "label": "Campos bloqueados", "value": str(len(dataset.blocked_fields)), "description": "Campos sensiveis e mensagens livres que permanecem fora da operacao administrativa.", }, { "key": "freshness_target", "label": "Meta de frescor", "value": dataset.freshness_target.value, "description": "Objetivo inicial de consolidacao para a UX dos relatorios operacionais do fluxo do bot.", }, ], "materialization": self._build_materialization_payload(dataset), "reports": [self._serialize_bot_flow_report_summary(report) for report in _BOT_FLOW_REPORTS], "next_steps": [ "Materializar snapshot sanitizado de conversation_turns no banco administrativo.", "Criar dedicated views separadas para status do turno, roteamento operacional e falhas do fluxo.", "Reservar latencia e eficiencia detalhada para a etapa seguinte de telemetria conversacional.", ], } def list_bot_flow_reports_payload(self) -> dict: dataset = self._get_bot_flow_dataset() return { "area": "fluxo_bot", "source_domain": dataset.domain, "source": _REPORT_SOURCE, "materialization": self._build_materialization_payload(dataset), "reports": [self._serialize_bot_flow_report_summary(report) for report in _BOT_FLOW_REPORTS], } def get_bot_flow_report_payload(self, report_key: str) -> dict | None: normalized_report_key = self._normalize_key(report_key) dataset = self._get_bot_flow_dataset() for report in _BOT_FLOW_REPORTS: if report["report_key"] == normalized_report_key: return { "area": "fluxo_bot", "source_domain": dataset.domain, "source": _REPORT_SOURCE, "materialization": self._build_materialization_payload(dataset), "report": self._serialize_bot_flow_report_detail(report, dataset), } return None def build_conversation_telemetry_overview_payload(self) -> dict: dataset = self._get_conversation_telemetry_dataset() return { "area": "telemetria_conversacional", "source_domain": dataset.domain, "mode": "conversation_telemetry_contract_bootstrap", "source_dataset_keys": [dataset.dataset_key], "metrics": [ { "key": "source_datasets", "label": "Datasets fonte", "value": "1", "description": "A estrutura inicial de telemetria conversacional nasce apoiada em um dataset sanitizado de turnos.", }, { "key": "initial_reports", "label": "Relatorios iniciais", "value": str(len(_CONVERSATION_TELEMETRY_REPORTS)), "description": "Casos de uso iniciais de observabilidade conversacional previstos para a primeira superficie administrativa.", }, { "key": "allowed_fields", "label": "Campos liberados", "value": str(len(dataset.allowed_fields)), "description": "Campos expostos para volume, latencia, distribuicao por dominio e uso de tools.", }, { "key": "blocked_fields", "label": "Campos bloqueados", "value": str(len(dataset.blocked_fields)), "description": "Campos sensiveis e texto livre que permanecem fora da telemetria administrativa.", }, { "key": "freshness_target", "label": "Meta de frescor", "value": dataset.freshness_target.value, "description": "Objetivo inicial de consolidacao para a UX dos relatorios de telemetria conversacional.", }, ], "materialization": self._build_materialization_payload(dataset), "reports": [self._serialize_conversation_telemetry_report_summary(report) for report in _CONVERSATION_TELEMETRY_REPORTS], "next_steps": [ "Materializar snapshot sanitizado de conversation_turns no banco administrativo.", "Criar dedicated views separadas para volume, latencia e distribuicao por dominio do atendimento.", "Preparar buckets e watermark de consolidacao para comparativos historicos da telemetria.", ], } def list_conversation_telemetry_reports_payload(self) -> dict: dataset = self._get_conversation_telemetry_dataset() return { "area": "telemetria_conversacional", "source_domain": dataset.domain, "source": _REPORT_SOURCE, "materialization": self._build_materialization_payload(dataset), "reports": [self._serialize_conversation_telemetry_report_summary(report) for report in _CONVERSATION_TELEMETRY_REPORTS], } def get_conversation_telemetry_report_payload(self, report_key: str) -> dict | None: normalized_report_key = self._normalize_key(report_key) dataset = self._get_conversation_telemetry_dataset() for report in _CONVERSATION_TELEMETRY_REPORTS: if report["report_key"] == normalized_report_key: return { "area": "telemetria_conversacional", "source_domain": dataset.domain, "source": _REPORT_SOURCE, "materialization": self._build_materialization_payload(dataset), "report": self._serialize_conversation_telemetry_report_detail(report, dataset), } return None @staticmethod def _build_materialization_payload(dataset: OperationalDatasetContract | None = None) -> dict: reference_dataset = dataset or PRODUCT_OPERATIONAL_DATASETS[0] return { "report_read_model": reference_dataset.report_read_model, "consistency_model": reference_dataset.consistency_model, "sync_strategy": reference_dataset.sync_strategy, "storage_shape": reference_dataset.storage_shape, "query_surface": reference_dataset.query_surface, "uses_product_replica": reference_dataset.uses_product_replica, "direct_product_query_allowed": reference_dataset.direct_product_query_allowed, "refresh_behavior": _REFRESH_BEHAVIOR, } @staticmethod def _serialize_dataset_summary(dataset) -> dict: return { "dataset_key": dataset.dataset_key, "domain": dataset.domain, "description": dataset.description, "source_table": dataset.source_table, "freshness_target": dataset.freshness_target, "allowed_granularities": list(dataset.allowed_granularities), "allowed_field_count": len(dataset.allowed_fields), "blocked_field_count": len(dataset.blocked_fields), "write_allowed": dataset.write_allowed, "materialization_status": _MATERIALIZATION_STATUS, "last_consolidated_at": None, "source_watermark": None, } @classmethod def _serialize_dataset_detail(cls, dataset) -> dict: return { "dataset_key": dataset.dataset_key, "domain": dataset.domain, "description": dataset.description, "source_table": dataset.source_table, "read_permission": dataset.read_permission, "report_read_model": dataset.report_read_model, "consistency_model": dataset.consistency_model, "sync_strategy": dataset.sync_strategy, "storage_shape": dataset.storage_shape, "query_surface": dataset.query_surface, "uses_product_replica": dataset.uses_product_replica, "direct_product_query_allowed": dataset.direct_product_query_allowed, "freshness_target": dataset.freshness_target, "allowed_granularities": list(dataset.allowed_granularities), "write_allowed": dataset.write_allowed, "materialization_status": _MATERIALIZATION_STATUS, "last_consolidated_at": None, "source_watermark": None, "allowed_fields": [cls._serialize_field(field) for field in dataset.allowed_fields], "blocked_fields": [cls._serialize_field(field) for field in dataset.blocked_fields], } @classmethod def _serialize_sales_report_summary(cls, report_definition: dict) -> dict: return { "report_key": report_definition["report_key"], "label": report_definition["label"], "description": report_definition["description"], "dataset_key": _SALES_DATASET_KEY, "default_time_field": report_definition["default_time_field"], "default_granularity": report_definition["default_granularity"], "supported_metric_keys": list(report_definition["metric_keys"]), "supported_dimension_fields": list(report_definition["dimension_fields"]), "materialization_status": _MATERIALIZATION_STATUS, "last_consolidated_at": None, "source_watermark": None, } @classmethod def _serialize_sales_report_detail( cls, report_definition: dict, dataset: OperationalDatasetContract, ) -> dict: return { "report_key": report_definition["report_key"], "label": report_definition["label"], "description": report_definition["description"], "dataset_key": _SALES_DATASET_KEY, "default_time_field": report_definition["default_time_field"], "default_granularity": report_definition["default_granularity"], "metrics": [dict(_SALES_REPORT_METRICS[key]) for key in report_definition["metric_keys"]], "dimensions": [dict(_SALES_DIMENSIONS[field_name]) for field_name in report_definition["dimension_fields"]], "filters": [dict(_SALES_FILTERS[field_name]) for field_name in report_definition["filter_fields"]], "dataset": cls._serialize_dataset_detail(dataset), } @classmethod def _serialize_revenue_report_summary(cls, report_definition: dict) -> dict: return { "report_key": report_definition["report_key"], "label": report_definition["label"], "description": report_definition["description"], "dataset_key": _REVENUE_DATASET_KEY, "default_time_field": report_definition["default_time_field"], "default_granularity": report_definition["default_granularity"], "supported_metric_keys": list(report_definition["metric_keys"]), "supported_dimension_fields": list(report_definition["dimension_fields"]), "materialization_status": _MATERIALIZATION_STATUS, "last_consolidated_at": None, "source_watermark": None, } @classmethod def _serialize_revenue_report_detail( cls, report_definition: dict, dataset: OperationalDatasetContract, ) -> dict: return { "report_key": report_definition["report_key"], "label": report_definition["label"], "description": report_definition["description"], "dataset_key": _REVENUE_DATASET_KEY, "default_time_field": report_definition["default_time_field"], "default_granularity": report_definition["default_granularity"], "metrics": [dict(_REVENUE_REPORT_METRICS[key]) for key in report_definition["metric_keys"]], "dimensions": [dict(_REVENUE_DIMENSIONS[field_name]) for field_name in report_definition["dimension_fields"]], "filters": [dict(_REVENUE_FILTERS[field_name]) for field_name in report_definition["filter_fields"]], "dataset": cls._serialize_dataset_detail(dataset), } @classmethod def _serialize_rental_report_summary(cls, report_definition: dict) -> dict: return { "report_key": report_definition["report_key"], "label": report_definition["label"], "description": report_definition["description"], "dataset_key": report_definition["dataset_key"], "default_time_field": report_definition["default_time_field"], "default_granularity": report_definition["default_granularity"], "supported_metric_keys": list(report_definition["metric_keys"]), "supported_dimension_fields": list(report_definition["dimension_fields"]), "materialization_status": _MATERIALIZATION_STATUS, "last_consolidated_at": None, "source_watermark": None, } @classmethod def _serialize_rental_report_detail( cls, report_definition: dict, dataset: OperationalDatasetContract, ) -> dict: return { "report_key": report_definition["report_key"], "label": report_definition["label"], "description": report_definition["description"], "dataset_key": report_definition["dataset_key"], "default_time_field": report_definition["default_time_field"], "default_granularity": report_definition["default_granularity"], "metrics": [dict(_RENTAL_REPORT_METRICS[key]) for key in report_definition["metric_keys"]], "dimensions": [dict(_RENTAL_DIMENSIONS[field_name]) for field_name in report_definition["dimension_fields"]], "filters": [dict(_RENTAL_FILTERS[field_name]) for field_name in report_definition["filter_fields"]], "dataset": cls._serialize_dataset_detail(dataset), } @classmethod def _serialize_bot_flow_report_summary(cls, report_definition: dict) -> dict: return { "report_key": report_definition["report_key"], "label": report_definition["label"], "description": report_definition["description"], "dataset_key": _BOT_FLOW_DATASET_KEY, "default_time_field": report_definition["default_time_field"], "default_granularity": report_definition["default_granularity"], "supported_metric_keys": list(report_definition["metric_keys"]), "supported_dimension_fields": list(report_definition["dimension_fields"]), "materialization_status": _MATERIALIZATION_STATUS, "last_consolidated_at": None, "source_watermark": None, } @classmethod def _serialize_bot_flow_report_detail( cls, report_definition: dict, dataset: OperationalDatasetContract, ) -> dict: return { "report_key": report_definition["report_key"], "label": report_definition["label"], "description": report_definition["description"], "dataset_key": _BOT_FLOW_DATASET_KEY, "default_time_field": report_definition["default_time_field"], "default_granularity": report_definition["default_granularity"], "metrics": [dict(_BOT_FLOW_REPORT_METRICS[key]) for key in report_definition["metric_keys"]], "dimensions": [dict(_BOT_FLOW_DIMENSIONS[field_name]) for field_name in report_definition["dimension_fields"]], "filters": [dict(_BOT_FLOW_FILTERS[field_name]) for field_name in report_definition["filter_fields"]], "dataset": cls._serialize_dataset_detail(dataset), } @classmethod def _serialize_conversation_telemetry_report_summary(cls, report_definition: dict) -> dict: return { "report_key": report_definition["report_key"], "label": report_definition["label"], "description": report_definition["description"], "dataset_key": _CONVERSATION_TELEMETRY_DATASET_KEY, "default_time_field": report_definition["default_time_field"], "default_granularity": report_definition["default_granularity"], "supported_metric_keys": list(report_definition["metric_keys"]), "supported_dimension_fields": list(report_definition["dimension_fields"]), "materialization_status": _MATERIALIZATION_STATUS, "last_consolidated_at": None, "source_watermark": None, } @classmethod def _serialize_conversation_telemetry_report_detail( cls, report_definition: dict, dataset: OperationalDatasetContract, ) -> dict: return { "report_key": report_definition["report_key"], "label": report_definition["label"], "description": report_definition["description"], "dataset_key": _CONVERSATION_TELEMETRY_DATASET_KEY, "default_time_field": report_definition["default_time_field"], "default_granularity": report_definition["default_granularity"], "metrics": [dict(_CONVERSATION_TELEMETRY_REPORT_METRICS[key]) for key in report_definition["metric_keys"]], "dimensions": [dict(_CONVERSATION_TELEMETRY_DIMENSIONS[field_name]) for field_name in report_definition["dimension_fields"]], "filters": [dict(_CONVERSATION_TELEMETRY_FILTERS[field_name]) for field_name in report_definition["filter_fields"]], "dataset": cls._serialize_dataset_detail(dataset), } @staticmethod def _serialize_field(field) -> dict: return { "name": field.name, "description": field.description, "sensitivity": field.sensitivity, } @staticmethod def _normalize_key(value: str) -> str: return str(value or "").strip().lower() @staticmethod def _get_sales_dataset() -> OperationalDatasetContract: dataset = get_operational_dataset(_SALES_DATASET_KEY) if dataset is None: raise RuntimeError("sales_orders contract is required to build sales reports") return dataset @staticmethod def _get_revenue_dataset() -> OperationalDatasetContract: dataset = get_operational_dataset(_REVENUE_DATASET_KEY) if dataset is None: raise RuntimeError("rental_payments contract is required to build revenue reports") return dataset @staticmethod def _get_rental_dataset(dataset_key: str) -> OperationalDatasetContract: dataset = get_operational_dataset(dataset_key) if dataset is None: raise RuntimeError(f"{dataset_key} contract is required to build rental reports") return dataset @classmethod def _get_rental_fleet_dataset(cls) -> OperationalDatasetContract: return cls._get_rental_dataset(_RENTAL_FLEET_DATASET_KEY) @classmethod def _get_rental_contracts_dataset(cls) -> OperationalDatasetContract: return cls._get_rental_dataset(_RENTAL_CONTRACTS_DATASET_KEY) @staticmethod def _get_bot_flow_dataset() -> OperationalDatasetContract: dataset = get_operational_dataset(_BOT_FLOW_DATASET_KEY) if dataset is None: raise RuntimeError("conversation_turns contract is required to build bot flow reports") return dataset @staticmethod def _get_conversation_telemetry_dataset() -> OperationalDatasetContract: dataset = get_operational_dataset(_CONVERSATION_TELEMETRY_DATASET_KEY) if dataset is None: raise RuntimeError("conversation_turns contract is required to build conversation telemetry reports") return dataset