mod dynamodb;
mod firebase;
mod sqlite;
use std::path::Path;
use std::sync::Arc;
use crate::infra::cluster::registry::WorkerRegistryRecord;
use crate::infra::execution::placement::ProjectRuntimePlacement;
use crate::platform::error::PlatformError;
use crate::platform::model::{
DataAdapterKind, MarketplaceAssetPackage, MarketplaceAssetVersion, MarketplaceAuthority,
MarketplacePublisher, MarketplaceToken, McpSession, PipelineInvocationEntry, PipelineMeta,
PlatformMarketplaceRepository, PlatformOffice, PlatformOfficeNode, PlatformProject,
PlatformServiceInstance, PlatformUser, ProjectCredential, ProjectDbConnection, ProjectInvite,
ProjectMarketplaceRepository, ProjectMember, ProjectOperationRecord, ProjectPolicy,
ProjectPolicyBinding, StoredUser,
};
pub trait DataAdapter: Send + Sync {
fn id(&self) -> &'static str;
fn get_user_auth(&self, owner: &str) -> Result<Option<StoredUser>, PlatformError>;
fn put_user(&self, user: &StoredUser) -> Result<(), PlatformError>;
fn list_users(&self) -> Result<Vec<PlatformUser>, PlatformError>;
fn get_project(
&self,
owner: &str,
project: &str,
) -> Result<Option<PlatformProject>, PlatformError>;
fn put_project(&self, project: &PlatformProject) -> Result<(), PlatformError>;
fn list_projects(&self, owner: &str) -> Result<Vec<PlatformProject>, PlatformError>;
fn delete_project(&self, owner: &str, project: &str) -> Result<(), PlatformError>;
fn get_project_credential(
&self,
owner: &str,
project: &str,
credential_id: &str,
) -> Result<Option<ProjectCredential>, PlatformError>;
fn put_project_credential(&self, credential: &ProjectCredential) -> Result<(), PlatformError>;
fn list_project_credentials(
&self,
owner: &str,
project: &str,
) -> Result<Vec<ProjectCredential>, PlatformError>;
fn delete_project_credential(
&self,
owner: &str,
project: &str,
credential_id: &str,
) -> Result<(), PlatformError>;
fn get_project_db_connection(
&self,
owner: &str,
project: &str,
connection_slug: &str,
) -> Result<Option<ProjectDbConnection>, PlatformError>;
fn put_project_db_connection(
&self,
connection: &ProjectDbConnection,
) -> Result<(), PlatformError>;
fn list_project_db_connections(
&self,
owner: &str,
project: &str,
) -> Result<Vec<ProjectDbConnection>, PlatformError>;
fn delete_project_db_connection(
&self,
owner: &str,
project: &str,
connection_slug: &str,
) -> Result<(), PlatformError>;
fn put_project_marketplace_repository(
&self,
repository: &ProjectMarketplaceRepository,
) -> Result<(), PlatformError> {
let _ = repository;
Err(PlatformError::new(
"PLATFORM_ADAPTER_UNAVAILABLE",
"marketplace repositories are not supported by this adapter",
))
}
fn list_project_marketplace_repositories(
&self,
owner: &str,
project: &str,
) -> Result<Vec<ProjectMarketplaceRepository>, PlatformError> {
let _ = (owner, project);
Ok(vec![])
}
fn delete_project_marketplace_repository(
&self,
owner: &str,
project: &str,
repository_id: &str,
) -> Result<(), PlatformError> {
let _ = (owner, project, repository_id);
Ok(())
}
fn put_platform_marketplace_repository(
&self,
repository: &PlatformMarketplaceRepository,
) -> Result<(), PlatformError> {
let _ = repository;
Err(PlatformError::new(
"PLATFORM_ADAPTER_UNAVAILABLE",
"platform marketplace repositories are not supported by this adapter",
))
}
fn list_platform_marketplace_repositories(
&self,
owner: &str,
) -> Result<Vec<PlatformMarketplaceRepository>, PlatformError> {
let _ = owner;
Ok(vec![])
}
fn delete_platform_marketplace_repository(
&self,
owner: &str,
repository_id: &str,
) -> Result<(), PlatformError> {
let _ = (owner, repository_id);
Ok(())
}
fn put_marketplace_publisher(
&self,
publisher: &MarketplacePublisher,
) -> Result<(), PlatformError> {
let _ = publisher;
Err(PlatformError::new(
"PLATFORM_ADAPTER_UNAVAILABLE",
"marketplace publishers are not supported by this adapter",
))
}
fn list_marketplace_publishers(
&self,
owner: &str,
project: &str,
) -> Result<Vec<MarketplacePublisher>, PlatformError> {
let _ = (owner, project);
Ok(vec![])
}
fn get_marketplace_publisher(
&self,
owner: &str,
project: &str,
publisher_id: &str,
) -> Result<Option<MarketplacePublisher>, PlatformError> {
let _ = (owner, project, publisher_id);
Ok(None)
}
fn delete_marketplace_publisher(
&self,
owner: &str,
project: &str,
publisher_id: &str,
) -> Result<(), PlatformError> {
let _ = (owner, project, publisher_id);
Ok(())
}
fn put_marketplace_asset_package(
&self,
package: &MarketplaceAssetPackage,
) -> Result<(), PlatformError> {
let _ = package;
Err(PlatformError::new(
"PLATFORM_ADAPTER_UNAVAILABLE",
"marketplace packages are not supported by this adapter",
))
}
fn list_marketplace_asset_packages(
&self,
) -> Result<Vec<MarketplaceAssetPackage>, PlatformError> {
Ok(vec![])
}
fn get_marketplace_asset_package(
&self,
package_id: &str,
) -> Result<Option<MarketplaceAssetPackage>, PlatformError> {
let _ = package_id;
Ok(None)
}
fn put_marketplace_asset_version(
&self,
version: &MarketplaceAssetVersion,
) -> Result<(), PlatformError> {
let _ = version;
Err(PlatformError::new(
"PLATFORM_ADAPTER_UNAVAILABLE",
"marketplace package versions are not supported by this adapter",
))
}
fn list_marketplace_asset_versions(
&self,
package_id: &str,
) -> Result<Vec<MarketplaceAssetVersion>, PlatformError> {
let _ = package_id;
Ok(vec![])
}
fn get_marketplace_asset_version(
&self,
package_id: &str,
version: &str,
) -> Result<Option<MarketplaceAssetVersion>, PlatformError> {
let _ = (package_id, version);
Ok(None)
}
fn put_marketplace_token(&self, token: &MarketplaceToken) -> Result<(), PlatformError> {
let _ = token;
Err(PlatformError::new(
"PLATFORM_ADAPTER_UNAVAILABLE",
"marketplace tokens are not supported by this adapter",
))
}
fn get_marketplace_token(
&self,
token_id: &str,
) -> Result<Option<MarketplaceToken>, PlatformError> {
let _ = token_id;
Ok(None)
}
fn list_marketplace_tokens(
&self,
owner: &str,
project: &str,
) -> Result<Vec<MarketplaceToken>, PlatformError> {
let _ = (owner, project);
Ok(vec![])
}
fn list_all_marketplace_tokens(&self) -> Result<Vec<MarketplaceToken>, PlatformError> {
Ok(vec![])
}
fn delete_marketplace_token(&self, token_id: &str) -> Result<(), PlatformError> {
let _ = token_id;
Ok(())
}
fn put_pipeline_meta(&self, meta: &PipelineMeta) -> Result<(), PlatformError>;
fn delete_pipeline_meta(
&self,
owner: &str,
project: &str,
file_rel_path: &str,
) -> Result<(), PlatformError>;
fn list_pipeline_meta(
&self,
owner: &str,
project: &str,
) -> Result<Vec<PipelineMeta>, PlatformError>;
fn put_project_policy(&self, policy: &ProjectPolicy) -> Result<(), PlatformError>;
fn list_project_policies(
&self,
owner: &str,
project: &str,
) -> Result<Vec<ProjectPolicy>, PlatformError>;
fn put_project_policy_binding(
&self,
binding: &ProjectPolicyBinding,
) -> Result<(), PlatformError>;
fn list_project_policy_bindings(
&self,
owner: &str,
project: &str,
) -> Result<Vec<ProjectPolicyBinding>, PlatformError>;
fn delete_project_policy(
&self,
owner: &str,
project: &str,
policy_id: &str,
) -> Result<(), PlatformError>;
fn delete_project_policy_binding(
&self,
owner: &str,
project: &str,
subject_id: &str,
) -> Result<(), PlatformError>;
fn get_project_member(
&self,
owner: &str,
project: &str,
user_id: &str,
) -> Result<Option<ProjectMember>, PlatformError>;
fn put_project_member(&self, member: &ProjectMember) -> Result<(), PlatformError>;
fn list_project_members(
&self,
owner: &str,
project: &str,
) -> Result<Vec<ProjectMember>, PlatformError>;
fn delete_project_member(
&self,
owner: &str,
project: &str,
user_id: &str,
) -> Result<(), PlatformError>;
fn get_project_invite(
&self,
owner: &str,
project: &str,
invite_id: &str,
) -> Result<Option<ProjectInvite>, PlatformError>;
fn put_project_invite(&self, invite: &ProjectInvite) -> Result<(), PlatformError>;
fn list_project_invites(
&self,
owner: &str,
project: &str,
) -> Result<Vec<ProjectInvite>, PlatformError>;
fn delete_project_invite(
&self,
owner: &str,
project: &str,
invite_id: &str,
) -> Result<(), PlatformError>;
fn get_marketplace_authority(
&self,
owner: &str,
project: &str,
) -> Result<Option<MarketplaceAuthority>, PlatformError> {
let _ = (owner, project);
Ok(None)
}
fn put_marketplace_authority(
&self,
authority: &MarketplaceAuthority,
) -> Result<(), PlatformError> {
let _ = authority;
Err(PlatformError::new(
"PLATFORM_ADAPTER_UNAVAILABLE",
"marketplace authorities are not supported by this adapter",
))
}
fn list_marketplace_authorities(&self) -> Result<Vec<MarketplaceAuthority>, PlatformError> {
Ok(vec![])
}
fn get_platform_office(
&self,
office_id: &str,
) -> Result<Option<PlatformOffice>, PlatformError> {
let _ = office_id;
Ok(None)
}
fn put_platform_office(&self, office: &PlatformOffice) -> Result<(), PlatformError> {
let _ = office;
Err(PlatformError::new(
"PLATFORM_ADAPTER_UNAVAILABLE",
"platform offices are not supported by this adapter",
))
}
fn list_platform_offices(&self) -> Result<Vec<PlatformOffice>, PlatformError> {
Ok(vec![])
}
fn get_platform_service_instance(
&self,
service_instance_id: &str,
) -> Result<Option<PlatformServiceInstance>, PlatformError> {
let _ = service_instance_id;
Ok(None)
}
fn put_platform_service_instance(
&self,
service: &PlatformServiceInstance,
) -> Result<(), PlatformError> {
let _ = service;
Err(PlatformError::new(
"PLATFORM_ADAPTER_UNAVAILABLE",
"platform service instances are not supported by this adapter",
))
}
fn list_platform_service_instances(
&self,
) -> Result<Vec<PlatformServiceInstance>, PlatformError> {
Ok(vec![])
}
fn get_platform_office_node(
&self,
node_id: &str,
) -> Result<Option<PlatformOfficeNode>, PlatformError> {
let _ = node_id;
Ok(None)
}
fn put_platform_office_node(&self, node: &PlatformOfficeNode) -> Result<(), PlatformError> {
let _ = node;
Err(PlatformError::new(
"PLATFORM_ADAPTER_UNAVAILABLE",
"platform office nodes are not supported by this adapter",
))
}
fn list_platform_office_nodes(&self) -> Result<Vec<PlatformOfficeNode>, PlatformError> {
Ok(vec![])
}
fn get_worker_registry_record(
&self,
node_id: &str,
) -> Result<Option<WorkerRegistryRecord>, PlatformError>;
fn put_worker_registry_record(
&self,
record: &WorkerRegistryRecord,
) -> Result<(), PlatformError>;
fn list_worker_registry_records(&self) -> Result<Vec<WorkerRegistryRecord>, PlatformError>;
fn delete_worker_registry_record(&self, node_id: &str) -> Result<(), PlatformError>;
fn get_project_runtime_placement(
&self,
owner: &str,
project: &str,
) -> Result<Option<ProjectRuntimePlacement>, PlatformError>;
fn put_project_runtime_placement(
&self,
placement: &ProjectRuntimePlacement,
) -> Result<(), PlatformError>;
fn list_project_runtime_placements(
&self,
) -> Result<Vec<ProjectRuntimePlacement>, PlatformError>;
fn delete_project_runtime_placement(
&self,
owner: &str,
project: &str,
) -> Result<(), PlatformError>;
fn get_project_operation(
&self,
owner: &str,
project: &str,
operation_id: &str,
) -> Result<Option<ProjectOperationRecord>, PlatformError> {
let _ = (owner, project, operation_id);
Err(PlatformError::new(
"PLATFORM_ADAPTER_UNAVAILABLE",
"project operations are not supported by this adapter",
))
}
fn put_project_operation(&self, record: &ProjectOperationRecord) -> Result<(), PlatformError> {
let _ = record;
Err(PlatformError::new(
"PLATFORM_ADAPTER_UNAVAILABLE",
"project operations are not supported by this adapter",
))
}
fn list_project_operations(
&self,
owner: &str,
project: &str,
limit: usize,
) -> Result<Vec<ProjectOperationRecord>, PlatformError> {
let _ = (owner, project, limit);
Ok(vec![])
}
fn list_all_mcp_sessions(&self) -> Result<Vec<McpSession>, PlatformError>;
fn put_mcp_session(&self, session: &McpSession) -> Result<(), PlatformError>;
fn delete_mcp_session(&self, token: &str) -> Result<(), PlatformError>;
fn admin_list_collections(&self) -> Result<Vec<(String, usize)>, PlatformError> {
Err(PlatformError::new(
"ADMIN_DB_UNAVAILABLE",
"Admin DB access not supported by this adapter",
))
}
fn admin_raw_query(
&self,
pipeline_json: &str,
) -> Result<Vec<serde_json::Value>, PlatformError> {
let _ = pipeline_json;
Err(PlatformError::new(
"ADMIN_DB_UNAVAILABLE",
"Admin DB access not supported by this adapter",
))
}
fn admin_get_node(&self, slug: &str) -> Result<Option<String>, PlatformError> {
let _ = slug;
Err(PlatformError::new(
"ADMIN_DB_UNAVAILABLE",
"Admin DB access not supported by this adapter",
))
}
fn admin_delete_node(&self, slug: &str) -> Result<bool, PlatformError> {
let _ = slug;
Err(PlatformError::new(
"ADMIN_DB_UNAVAILABLE",
"Admin DB access not supported by this adapter",
))
}
fn log_pipeline_invocation(
&self,
_owner: &str,
_project: &str,
_file_rel_path: &str,
_entry: &PipelineInvocationEntry,
_max_n: usize,
_max_age_secs: Option<i64>,
) -> Result<(), PlatformError> {
Ok(())
}
fn get_pipeline_invocations(
&self,
_owner: &str,
_project: &str,
_file_rel_path: &str,
_max_age_secs: Option<i64>,
) -> Result<Vec<PipelineInvocationEntry>, PlatformError> {
Ok(vec![])
}
fn transfer_project_owner(
&self,
_old_owner: &str,
_project: &str,
_new_owner: &str,
_new_owner_user_id: &str,
) -> Result<(), PlatformError> {
Err(PlatformError::new(
"PLATFORM_ADAPTER_UNAVAILABLE",
"transfer_project_owner not supported by this adapter",
))
}
}
pub fn build_data_adapter(
kind: DataAdapterKind,
data_root: &Path,
) -> Result<Arc<dyn DataAdapter>, PlatformError> {
match kind {
DataAdapterKind::Sqlite => Ok(Arc::new(sqlite::SqliteDataAdapter::new(data_root)?)),
DataAdapterKind::DynamoDb => Ok(Arc::new(dynamodb::DynamoDbDataAdapter::default())),
DataAdapterKind::Firebase => Ok(Arc::new(firebase::FirebaseDataAdapter::default())),
}
}
pub fn build_marketplace_data_adapter(
kind: DataAdapterKind,
db_path: &Path,
) -> Result<Arc<dyn DataAdapter>, PlatformError> {
match kind {
DataAdapterKind::Sqlite => Ok(Arc::new(sqlite::SqliteDataAdapter::new_at_db_path(
db_path,
)?)),
DataAdapterKind::DynamoDb | DataAdapterKind::Firebase => Err(PlatformError::new(
"PLATFORM_MARKETPLACE_ADAPTER_UNAVAILABLE",
"office-hosted marketplace service storage currently requires sqlite",
)),
}
}