use serde::{Deserialize, Serialize}; use time::OffsetDateTime; use crate::{AgentId, InvocationLogId, OperationId, PlatformApiKeyId, WorkspaceId}; #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] pub enum OnboardingStepId { Operation, Test, PublishOperation, Agent, Key, McpConnection, FirstCall, } impl OnboardingStepId { pub const ORDERED: [Self; 7] = [ Self::Operation, Self::Test, Self::PublishOperation, Self::Agent, Self::Key, Self::McpConnection, Self::FirstCall, ]; } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct OnboardingStep { pub id: OnboardingStepId, pub completed: bool, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct OnboardingProjection { pub workspace_id: WorkspaceId, pub revision: i64, pub completed: bool, pub was_completed: bool, pub steps: Vec, pub operation_id: Option, pub operation_version: Option, pub agent_id: Option, pub catalog_revision: Option, pub platform_api_key_id: Option, pub first_call_log_id: Option, pub first_call_tool_name: Option, #[serde(with = "time::serde::rfc3339::option")] pub first_call_at: Option, pub first_call_request_id: Option, pub first_call_trace_id: Option, #[serde(with = "time::serde::rfc3339::option")] pub eligible_since: Option, } impl OnboardingProjection { pub fn step(&self, id: OnboardingStepId) -> Option<&OnboardingStep> { self.steps.iter().find(|step| step.id == id) } }