Skip to main content

mz_frontegg_mock/models/
tenant.rs

1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Use of this software is governed by the Business Source License
4// included in the LICENSE file.
5//
6// As of the Change Date specified in that file, in accordance with
7// the Business Source License, use of this software will be governed
8// by the Apache License, Version 2.0.
9
10use chrono::{DateTime, Utc};
11use serde::Serialize;
12use uuid::Uuid;
13
14/// Configuration for a tenant in the mock.
15#[derive(Debug, Clone)]
16pub struct TenantConfig {
17    pub id: Uuid,
18    pub name: String,
19    pub metadata: serde_json::Value,
20    pub creator_name: Option<String>,
21    pub creator_email: Option<String>,
22    pub created_at: DateTime<Utc>,
23    pub updated_at: DateTime<Utc>,
24    pub deleted_at: Option<DateTime<Utc>>,
25}
26
27impl TenantConfig {
28    pub fn new(id: Uuid, name: impl Into<String>) -> Self {
29        let now = Utc::now();
30        Self {
31            id,
32            name: name.into(),
33            metadata: serde_json::json!({}),
34            creator_name: None,
35            creator_email: None,
36            created_at: now,
37            updated_at: now,
38            deleted_at: None,
39        }
40    }
41}
42
43/// Tenant response matching the Frontegg API format.
44///
45/// Only serializable: `metadata` is encoded as a nested JSON string, which is
46/// not decoded on the way back in.
47#[derive(Debug, Clone, Serialize)]
48#[serde(rename_all = "camelCase")]
49pub struct TenantResponse {
50    #[serde(rename = "tenantId")]
51    pub id: Uuid,
52    pub name: String,
53    /// Metadata serialized as a nested JSON string (what Frontegg API returns)
54    #[serde(serialize_with = "serialize_nested_json")]
55    pub metadata: serde_json::Value,
56    #[serde(skip_serializing_if = "Option::is_none")]
57    pub creator_name: Option<String>,
58    #[serde(skip_serializing_if = "Option::is_none")]
59    pub creator_email: Option<String>,
60    pub created_at: DateTime<Utc>,
61    pub updated_at: DateTime<Utc>,
62    pub deleted_at: Option<DateTime<Utc>>,
63}
64
65fn serialize_nested_json<S>(value: &serde_json::Value, serializer: S) -> Result<S::Ok, S::Error>
66where
67    S: serde::Serializer,
68{
69    // Serialize the value as a JSON string
70    let json_string = serde_json::to_string(value).map_err(serde::ser::Error::custom)?;
71    serializer.serialize_str(&json_string)
72}
73
74impl From<&TenantConfig> for TenantResponse {
75    fn from(config: &TenantConfig) -> Self {
76        Self {
77            id: config.id,
78            name: config.name.clone(),
79            metadata: config.metadata.clone(),
80            creator_name: config.creator_name.clone(),
81            creator_email: config.creator_email.clone(),
82            created_at: config.created_at,
83            updated_at: config.updated_at,
84            deleted_at: config.deleted_at,
85        }
86    }
87}