Start CQRS refactoring: Create Osiris client crate
- Added workspace structure to Osiris Cargo.toml - Created osiris-client crate for query operations (GET requests) - Implemented generic get(), list(), query() methods - Added KYC, payment, and communication query modules - Created comprehensive refactoring plan document CQRS Pattern: - Commands (writes) → Supervisor client → Rhai scripts - Queries (reads) → Osiris client → REST API Next steps: - Implement Osiris server with Axum - Restructure SDK client by category (kyc/, payment/, etc.) - Update FreezoneClient to use both supervisor and osiris clients
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
# OSIRIS Architecture - Trait-Based Generic Objects
|
||||
# OSIRIS Architecture
|
||||
|
||||
## Overview
|
||||
|
||||
OSIRIS has been refactored to use a trait-based architecture similar to heromodels, allowing any object implementing the `Object` trait to be stored and indexed automatically based on field attributes.
|
||||
OSIRIS uses a trait-based architecture for storing and retrieving typed objects with automatic indexing, Rhai scripting support, and signatory-based access control.
|
||||
|
||||
## Core Concepts
|
||||
|
||||
@@ -311,100 +311,59 @@ When an object is deleted:
|
||||
3. **Remove** from all indexes
|
||||
4. **Delete** the object
|
||||
|
||||
## Comparison with heromodels
|
||||
## Rhai Integration
|
||||
|
||||
| Feature | heromodels | OSIRIS |
|
||||
|---------|-----------|--------|
|
||||
| Base struct | `BaseModelData` | `BaseData` |
|
||||
| Core trait | `Model` | `Object` |
|
||||
| ID type | `u32` (auto-increment) | `String` (UUID) |
|
||||
| Timestamps | `i64` (Unix) | `OffsetDateTime` |
|
||||
| Index macro | `#[index]` (derive) | Manual `index_keys()` |
|
||||
| Storage | OurDB/Postgres | HeroDB (Redis) |
|
||||
| Serialization | CBOR/JSON | JSON |
|
||||
OSIRIS provides full Rhai scripting support through the `rhai` module:
|
||||
|
||||
## Future Enhancements
|
||||
### OsirisContext
|
||||
|
||||
### 1. Derive Macro for #[index]
|
||||
|
||||
Create a proc macro to automatically generate `index_keys()` from field attributes:
|
||||
Multi-tenant context with signatory-based access control:
|
||||
|
||||
```rust
|
||||
#[derive(Object)]
|
||||
pub struct Note {
|
||||
pub base_data: BaseData,
|
||||
|
||||
#[index]
|
||||
pub title: Option<String>,
|
||||
|
||||
pub content: Option<String>,
|
||||
|
||||
#[index]
|
||||
pub tags: BTreeMap<String, String>,
|
||||
pub struct OsirisContext {
|
||||
context_id: String,
|
||||
participants: Vec<String>, // Public keys
|
||||
members: HashMap<String, Vec<Privilege>>,
|
||||
store: Arc<GenericStore>,
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Query Builder
|
||||
**Key Features:**
|
||||
- **Signatory-based access**: All participants must be signatories
|
||||
- **Member management**: Add/remove members with privileges
|
||||
- **Generic CRUD**: `save()`, `get()`, `delete()`, `list()`, `query()`
|
||||
|
||||
Type-safe query builder for indexed fields:
|
||||
### Rhai API
|
||||
|
||||
Each object type provides Rhai bindings in its `rhai.rs` file:
|
||||
|
||||
```rust
|
||||
let results = store
|
||||
.query::<Note>("notes")
|
||||
.filter("tag:topic", "rust")
|
||||
.filter("tag:priority", "high")
|
||||
.limit(10)
|
||||
.execute()
|
||||
.await?;
|
||||
```
|
||||
|
||||
### 3. Relations
|
||||
|
||||
Support for typed relations between objects:
|
||||
|
||||
```rust
|
||||
pub struct Note {
|
||||
pub base_data: BaseData,
|
||||
pub title: String,
|
||||
#[export_module]
|
||||
mod rhai_note_module {
|
||||
#[rhai_fn(name = "note", return_raw)]
|
||||
pub fn new_note(ns: String) -> Result<Note, Box<EvalAltResult>> {
|
||||
Ok(Note::new(ns))
|
||||
}
|
||||
|
||||
#[relation(target = "Note", label = "references")]
|
||||
pub references: Vec<String>,
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Validation
|
||||
|
||||
Trait-based validation:
|
||||
|
||||
```rust
|
||||
pub trait Validate {
|
||||
fn validate(&self) -> Result<()>;
|
||||
}
|
||||
|
||||
impl Validate for Note {
|
||||
fn validate(&self) -> Result<()> {
|
||||
if self.title.is_none() {
|
||||
return Err(Error::InvalidInput("Title required".into()));
|
||||
}
|
||||
Ok(())
|
||||
#[rhai_fn(name = "title", return_raw)]
|
||||
pub fn set_title(note: Note, title: String) -> Result<Note, Box<EvalAltResult>> {
|
||||
Ok(note.title(title))
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Migration from Old API
|
||||
### Engine Configuration
|
||||
|
||||
The old `OsirisObject` API is still available for backwards compatibility:
|
||||
The runner binary supports multiple configurations:
|
||||
|
||||
```rust
|
||||
// Old API (still works)
|
||||
use osiris::store::OsirisObject;
|
||||
let obj = OsirisObject::new("notes".to_string(), Some("text".to_string()));
|
||||
```bash
|
||||
# Single instance
|
||||
cargo run --bin runner -- runner1 --redis-url redis://localhost:6379 --db-id 1
|
||||
|
||||
// New API (recommended)
|
||||
use osiris::objects::Note;
|
||||
let note = Note::new("notes".to_string())
|
||||
.set_title("Title")
|
||||
.set_content("text");
|
||||
# Multiple predefined instances
|
||||
cargo run --bin runner -- runner1 \
|
||||
--instance freezone:redis://localhost:6379:1 \
|
||||
--instance my:redis://localhost:6379:2
|
||||
```
|
||||
|
||||
## Benefits of Trait-Based Architecture
|
||||
@@ -418,9 +377,12 @@ let note = Note::new("notes".to_string())
|
||||
|
||||
## Summary
|
||||
|
||||
The trait-based architecture makes OSIRIS:
|
||||
- **More flexible**: Any type can be stored by implementing `Object`
|
||||
- **More consistent**: Follows heromodels patterns
|
||||
- **More powerful**: Automatic indexing based on object structure
|
||||
- **More maintainable**: Clear separation of concerns
|
||||
- **More extensible**: Easy to add new object types and features
|
||||
OSIRIS provides:
|
||||
- **Type-safe storage**: Any type implementing `Object` can be stored
|
||||
- **Automatic indexing**: Fields marked with `#[index]` are automatically indexed
|
||||
- **Rhai scripting**: Full scripting support with builder patterns
|
||||
- **Multi-tenant contexts**: Signatory-based access control
|
||||
- **HeroDB backend**: Redis-compatible storage with encryption
|
||||
- **Extensibility**: Easy to add new object types and features
|
||||
|
||||
See [CREATING_NEW_OBJECTS.md](CREATING_NEW_OBJECTS.md) for a guide on creating custom objects.
|
||||
|
||||
Reference in New Issue
Block a user