use std::collections::HashMap;
use chrono::Utc;
use serde_json::Value as JsonValue;
#[derive(Debug, Clone)]
pub struct TenantContext {
id: String,
created_at: String,
metadata: HashMap<String, String>,
}
impl TenantContext {
#[must_use]
pub fn new(id: impl Into<String>) -> Self {
Self {
id: id.into(),
created_at: Utc::now().to_rfc3339(),
metadata: HashMap::new(),
}
}
#[must_use]
pub fn id(&self) -> &str {
&self.id
}
#[must_use]
pub fn created_at_iso8601(&self) -> Option<&str> {
if self.created_at.is_empty() {
None
} else {
Some(&self.created_at)
}
}
pub fn set_metadata(&mut self, key: impl Into<String>, value: impl Into<String>) {
self.metadata.insert(key.into(), value.into());
}
#[must_use]
pub fn get_metadata(&self, key: &str) -> Option<&str> {
self.metadata.get(key).map(String::as_str)
}
#[must_use]
pub const fn metadata(&self) -> &HashMap<String, String> {
&self.metadata
}
pub fn from_jwt_claims(claims: &JsonValue) -> Result<Self, String> {
let tenant_id = claims
.get("tenant_id")
.and_then(|v| v.as_str())
.ok_or_else(|| "Missing or invalid 'tenant_id' claim in JWT".to_string())?;
Ok(Self::new(tenant_id))
}
}
#[cfg(test)]
mod tests;