haste_server/
tenants.rs

1use crate::{fhir_client::ServerCTX, services::AppState};
2use clap::ValueEnum;
3use haste_fhir_client::FHIRClient;
4use haste_fhir_model::r4::generated::{
5    resources::{Project, Resource, ResourceType},
6    types::FHIRString,
7};
8use haste_fhir_operation_error::OperationOutcomeError;
9use haste_fhir_search::SearchEngine;
10use haste_fhir_terminology::FHIRTerminology;
11use haste_jwt::{ProjectId, TenantId};
12use haste_repository::{
13    Repository, admin::TenantAuthAdmin, types::tenant::CreateTenant, utilities::generate_id,
14};
15use std::sync::Arc;
16
17#[derive(Debug, Clone, ValueEnum)]
18pub enum SubscriptionTier {
19    Free,
20    Professional,
21    Team,
22    Unlimited,
23}
24
25impl From<SubscriptionTier> for String {
26    fn from(tier: SubscriptionTier) -> Self {
27        match tier {
28            SubscriptionTier::Free => "free".to_string(),
29            SubscriptionTier::Professional => "professional".to_string(),
30            SubscriptionTier::Team => "team".to_string(),
31            SubscriptionTier::Unlimited => "unlimited".to_string(),
32        }
33    }
34}
35
36pub async fn create_tenant<
37    Repo: Repository + Send + Sync + 'static,
38    Search: SearchEngine + Send + Sync + 'static,
39    Terminology: FHIRTerminology + Send + Sync + 'static,
40>(
41    services: Arc<AppState<Repo, Search, Terminology>>,
42    id: Option<String>,
43    _name: &str,
44    subscription_tier: &SubscriptionTier,
45) -> Result<(), OperationOutcomeError> {
46    let services = services.transaction().await?;
47
48    let new_tenant = TenantAuthAdmin::create(
49        &*services.repo,
50        &TenantId::System,
51        CreateTenant {
52            id: Some(TenantId::new(id.unwrap_or(generate_id(Some(16))))),
53            subscription_tier: Some(subscription_tier.clone().into()),
54        },
55    )
56    .await?;
57
58    services
59        .fhir_client
60        .create(
61            Arc::new(ServerCTX::system(
62                new_tenant.id,
63                ProjectId::System,
64                services.fhir_client.clone(),
65            )),
66            ResourceType::Project,
67            Resource::Project(Project {
68                id: Some(ProjectId::System.to_string()),
69                name: Box::new(FHIRString {
70                    value: Some(ProjectId::System.to_string()),
71                    ..Default::default()
72                }),
73                fhirVersion: Box::new(
74                    haste_fhir_model::r4::generated::terminology::SupportedFhirVersion::R4(None),
75                ),
76                ..Default::default()
77            }),
78        )
79        .await?;
80
81    services.commit().await?;
82
83    Ok(())
84}