Skip to main content

types_registry_sdk/
api.rs

1//! `TypesRegistryClient` trait definition.
2//!
3//! This trait defines the public API for the `types-registry` module.
4//! GTS type-schemas and instances are global resources, so no security context
5//! is required.
6
7use std::collections::HashMap;
8
9use async_trait::async_trait;
10use uuid::Uuid;
11
12use crate::error::TypesRegistryError;
13use crate::models::{GtsInstance, GtsTypeSchema, InstanceQuery, RegisterResult, TypeSchemaQuery};
14
15/// Public API trait for the `types-registry` module.
16///
17/// This trait can be consumed by other modules via `ClientHub`:
18/// ```ignore
19/// let client = hub.get::<dyn TypesRegistryClient>()?;
20/// let schema = client.get_type_schema("gts.acme.core.events.user.v1~").await?;
21/// ```
22///
23/// GTS type-schemas and instances are global resources (not tenant-scoped),
24/// so no security context is required for these operations.
25#[async_trait]
26pub trait TypesRegistryClient: Send + Sync {
27    // ------------------------------------------------------------------
28    // Generic batch register (kind detected from gts_id suffix per item).
29    // ------------------------------------------------------------------
30
31    /// Register GTS entities (type-schemas or instances) in batch.
32    ///
33    /// Each JSON value must contain a valid GTS identifier in one of the
34    /// configured ID fields (`$id`, `gtsId`, `id`). The batch is sorted
35    /// lexicographically by GTS id before processing so parents are
36    /// registered before their children within the same batch.
37    ///
38    /// Per-item failures are reported via [`RegisterResult::Err`]; success
39    /// carries only the canonical [`gts_id`](RegisterResult::Ok). To inspect
40    /// the typed view of a registered entity, follow up with
41    /// [`Self::get_type_schema`] / [`Self::get_instance`].
42    ///
43    /// # Errors
44    ///
45    /// Returns `Err` only for catastrophic failures (e.g., backend unavailable).
46    async fn register(
47        &self,
48        entities: Vec<serde_json::Value>,
49    ) -> Result<Vec<RegisterResult>, TypesRegistryError>;
50
51    // ------------------------------------------------------------------
52    // Type-schema operations (internal — no tenant scoping).
53    // ------------------------------------------------------------------
54
55    /// Register GTS type-schemas in batch.
56    ///
57    /// Each input value must have a GTS id ending with `~`. Inputs whose
58    /// identifier does not match the type-schema kind are returned as
59    /// per-item `RegisterResult::Err` with `InvalidGtsTypeId`. In ready
60    /// phase, items whose chain parent is not yet registered fail with
61    /// `ParentTypeSchemaNotRegistered` (callers may register the parent
62    /// then retry the failed item).
63    ///
64    /// # Errors
65    ///
66    /// Returns `Err` only for catastrophic failures.
67    async fn register_type_schemas(
68        &self,
69        type_schemas: Vec<serde_json::Value>,
70    ) -> Result<Vec<RegisterResult>, TypesRegistryError>;
71
72    /// Retrieve a registered GTS type-schema by its type id.
73    ///
74    /// # Errors
75    ///
76    /// * `GtsTypeSchemaNotFound` — no type-schema with this id is registered.
77    /// * `InvalidGtsTypeId` — id format is invalid, kind-mismatched, or
78    ///   resolves to a non-type-schema entity.
79    async fn get_type_schema(&self, type_id: &str) -> Result<GtsTypeSchema, TypesRegistryError>;
80
81    /// Retrieve a registered GTS type-schema by its deterministic UUID v5.
82    ///
83    /// # Errors
84    ///
85    /// * `GtsTypeSchemaNotFound` — no type-schema is registered with this UUID
86    ///   (also returned when the UUID exists but points to an instance).
87    async fn get_type_schema_by_uuid(
88        &self,
89        type_uuid: Uuid,
90    ) -> Result<GtsTypeSchema, TypesRegistryError>;
91
92    /// Retrieve multiple type-schemas by id in one call.
93    ///
94    /// Returns a map keyed by the input ids; each value is a per-item
95    /// `Result` carrying either the resolved schema or the per-item error
96    /// ([`GtsTypeSchemaNotFound`](TypesRegistryError::GtsTypeSchemaNotFound),
97    /// [`InvalidGtsTypeId`](TypesRegistryError::InvalidGtsTypeId), …).
98    /// Duplicate ids in the input collapse to a single entry. The map
99    /// always has a value for every distinct input id.
100    async fn get_type_schemas(
101        &self,
102        type_ids: Vec<String>,
103    ) -> HashMap<String, Result<GtsTypeSchema, TypesRegistryError>>;
104
105    /// Retrieve multiple type-schemas by deterministic UUID v5 in one call.
106    ///
107    /// Same per-key semantics as [`Self::get_type_schemas`]: a map keyed
108    /// by the input UUIDs, per-item failures carried in the inner
109    /// `Result`. Duplicates collapse.
110    async fn get_type_schemas_by_uuid(
111        &self,
112        type_uuids: Vec<Uuid>,
113    ) -> HashMap<Uuid, Result<GtsTypeSchema, TypesRegistryError>>;
114
115    /// List registered GTS type-schemas matching the query.
116    async fn list_type_schemas(
117        &self,
118        query: TypeSchemaQuery,
119    ) -> Result<Vec<GtsTypeSchema>, TypesRegistryError>;
120
121    // ------------------------------------------------------------------
122    // Instance operations (internal — no tenant scoping).
123    // ------------------------------------------------------------------
124
125    /// Register GTS instances in batch.
126    ///
127    /// Each input value must have a GTS id that does NOT end with `~`. Inputs
128    /// whose identifier does not match the instance kind are returned as
129    /// per-item `RegisterResult::Err` with `InvalidGtsInstanceId`. In ready
130    /// phase, items whose declaring type-schema is not yet registered fail
131    /// with `ParentTypeSchemaNotRegistered`.
132    ///
133    /// # Errors
134    ///
135    /// Returns `Err` only for catastrophic failures.
136    async fn register_instances(
137        &self,
138        instances: Vec<serde_json::Value>,
139    ) -> Result<Vec<RegisterResult>, TypesRegistryError>;
140
141    /// Retrieve a registered GTS instance by its instance id.
142    ///
143    /// # Errors
144    ///
145    /// * `GtsInstanceNotFound` — no instance with this id is registered.
146    /// * `InvalidGtsInstanceId` — id format is invalid, kind-mismatched, or
147    ///   resolves to a non-instance entity.
148    async fn get_instance(&self, id: &str) -> Result<GtsInstance, TypesRegistryError>;
149
150    /// Retrieve a registered GTS instance by its deterministic UUID v5.
151    ///
152    /// # Errors
153    ///
154    /// * `GtsInstanceNotFound` — no instance is registered with this UUID
155    ///   (also returned when the UUID exists but points to a type-schema).
156    async fn get_instance_by_uuid(&self, uuid: Uuid) -> Result<GtsInstance, TypesRegistryError>;
157
158    /// Retrieve multiple instances by id in one call.
159    ///
160    /// Returns a map keyed by the input ids; each value is a per-item
161    /// `Result` carrying either the resolved instance or the per-item
162    /// error ([`GtsInstanceNotFound`](TypesRegistryError::GtsInstanceNotFound),
163    /// [`InvalidGtsInstanceId`](TypesRegistryError::InvalidGtsInstanceId),
164    /// …). Duplicate ids in the input collapse to a single entry.
165    async fn get_instances(
166        &self,
167        ids: Vec<String>,
168    ) -> HashMap<String, Result<GtsInstance, TypesRegistryError>>;
169
170    /// Retrieve multiple instances by deterministic UUID v5 in one call.
171    ///
172    /// Same per-key semantics as [`Self::get_instances`]: a map keyed by
173    /// the input UUIDs, per-item failures carried in the inner `Result`.
174    /// Duplicates collapse.
175    async fn get_instances_by_uuid(
176        &self,
177        uuids: Vec<Uuid>,
178    ) -> HashMap<Uuid, Result<GtsInstance, TypesRegistryError>>;
179
180    /// List registered GTS instances matching the query.
181    async fn list_instances(
182        &self,
183        query: InstanceQuery,
184    ) -> Result<Vec<GtsInstance>, TypesRegistryError>;
185}