Major Changes:
- Moved Rhai support from rhai_support/ to rhai/ module
- Implemented context-based execution with signatory access control
- Added TypeRegistry for dynamic type registration and object creation
- Refactored engine to use context (Vec<String>) instead of instance
- Removed old runner binary (moved to runner_rust crate)
Rhai Module:
- engine.rs: Core Rhai engine with context-based get_context()
- functions.rs: Rhai function bindings (create_note, create_event, etc.)
- mod.rs: Module exports and organization
Store Improvements:
- TypeRegistry for registering object types and creators
- Generic store uses type registry for dynamic object creation
- Improved error handling and type safety
Documentation:
- RHAI_REFACTOR_COMPLETE.md: Refactoring details
- SIGNATORY_ACCESS_CONTROL.md: Context-based access control
- TYPE_REGISTRY_DESIGN.md: Type registry architecture
- REFACTORING_COMPLETE.md: Overall refactoring summary
- TESTS_COMPLETE.md: Testing documentation
Build Status: ✅ Compiles successfully with minor warnings
222 lines
5.4 KiB
Markdown
222 lines
5.4 KiB
Markdown
# OSIRIS Refactoring Complete! 🎉
|
|
|
|
## Summary
|
|
|
|
Successfully refactored OSIRIS with:
|
|
1. ✅ **Builder Pattern** for `OsirisContext`
|
|
2. ✅ **Type Registry** for custom struct registration
|
|
3. ✅ **Engine Module** moved to `rhai` module
|
|
4. ✅ **Simplified Runner** using the new architecture
|
|
|
|
---
|
|
|
|
## 1. Builder Pattern
|
|
|
|
### Before:
|
|
```rust
|
|
OsirisContext::new_with_registry(name, owner, url, db_id, registry)
|
|
```
|
|
|
|
### After:
|
|
```rust
|
|
let ctx = OsirisContext::builder()
|
|
.name("my_context")
|
|
.owner("user_123")
|
|
.herodb_url("redis://localhost:6379")
|
|
.db_id(1)
|
|
.registry(registry) // Optional
|
|
.build()?;
|
|
```
|
|
|
|
**Benefits:**
|
|
- Fluent, readable API
|
|
- Optional parameters
|
|
- Type-safe construction
|
|
- Backward compatible with `OsirisContext::new()`
|
|
|
|
---
|
|
|
|
## 2. Type Registry
|
|
|
|
### Architecture:
|
|
```rust
|
|
// 1. Create registry
|
|
let registry = TypeRegistry::new();
|
|
|
|
// 2. Register types (one line per type!)
|
|
registry.register_type::<Resident>("residents")?;
|
|
registry.register_type::<Company>("companies")?;
|
|
registry.register_type::<Invoice>("invoices")?;
|
|
|
|
// 3. Create context with registry
|
|
let ctx = OsirisContext::builder()
|
|
.name("zdfz")
|
|
.owner("admin")
|
|
.herodb_url(url)
|
|
.db_id(1)
|
|
.registry(Arc::new(registry))
|
|
.build()?;
|
|
|
|
// 4. Save uses the correct type automatically!
|
|
ctx.save("residents", "id123", resident_data)?; // Uses Resident type
|
|
ctx.save("companies", "id456", company_data)?; // Uses Company type
|
|
```
|
|
|
|
### How It Works:
|
|
1. **Registry maps collection → type**
|
|
2. **Single `save()` function** looks up the type
|
|
3. **Deserializes JSON** to the correct Rust struct
|
|
4. **Calls `store.put()`** with typed object
|
|
5. **Proper indexing** happens via `index_keys()` method
|
|
|
|
**No callbacks, no multiple functions - just ONE save function!** 🎯
|
|
|
|
---
|
|
|
|
## 3. Engine Module
|
|
|
|
### Moved from:
|
|
```
|
|
src/bin/runner/engine.rs
|
|
```
|
|
|
|
### To:
|
|
```
|
|
src/rhai/engine.rs
|
|
```
|
|
|
|
### New API:
|
|
```rust
|
|
use osiris::rhai::{
|
|
OsirisEngineConfig,
|
|
create_osiris_engine,
|
|
create_osiris_engine_with_config,
|
|
create_osiris_engine,
|
|
};
|
|
|
|
// Simple engine
|
|
let (engine, scope) = create_osiris_engine("owner", "redis://localhost:6379", 1)?;
|
|
|
|
// With config
|
|
let mut config = OsirisEngineConfig::new();
|
|
config.add_context("ctx1", "owner1", "redis://localhost:6379", 1);
|
|
config.add_context("ctx2", "owner2", "redis://localhost:6379", 2);
|
|
let (engine, scope) = create_osiris_engine_with_config(config)?;
|
|
|
|
// With context manager (dynamic contexts)
|
|
let engine = create_osiris_engine("redis://localhost:6379", 1)?;
|
|
```
|
|
|
|
---
|
|
|
|
## 4. Simplified Runner
|
|
|
|
### New Structure:
|
|
```
|
|
src/bin/runner.rs (single file!)
|
|
```
|
|
|
|
### Usage:
|
|
```bash
|
|
# Run a script
|
|
cargo run --bin runner --features rhai-support -- runner1 \
|
|
--script "ctx.save('residents', 'id123', data);"
|
|
|
|
# With custom contexts
|
|
cargo run --bin runner --features rhai-support -- runner1 \
|
|
--instance freezone:redis://localhost:6379:1 \
|
|
--instance backup:redis://localhost:6379:2 \
|
|
--script "freezone.save('residents', 'id123', data);"
|
|
```
|
|
|
|
---
|
|
|
|
## File Structure
|
|
|
|
```
|
|
osiris/src/
|
|
├── rhai/
|
|
│ ├── mod.rs # Exports
|
|
│ ├── instance.rs # OsirisContext + Builder + ContextManager
|
|
│ └── engine.rs # Engine creation functions
|
|
├── store/
|
|
│ ├── mod.rs
|
|
│ ├── generic_store.rs
|
|
│ └── type_registry.rs # Type registry for custom structs
|
|
└── bin/
|
|
└── runner.rs # Simplified runner binary
|
|
```
|
|
|
|
---
|
|
|
|
## Exports
|
|
|
|
From `osiris::rhai`:
|
|
- `OsirisContext` - Main context type
|
|
- `OsirisContextBuilder` - Builder for contexts
|
|
- `OsirisInstance` - Alias for backward compatibility
|
|
- `ContextManager` - Multi-tenant manager
|
|
- `Privilege`, `Member` - Access control types
|
|
- `OsirisEngineConfig` - Engine configuration
|
|
- `create_osiris_engine()` - Engine creation functions
|
|
- `register_context_api()` - Register context API in engine
|
|
|
|
From `osiris::store`:
|
|
- `TypeRegistry` - Type registry for custom structs
|
|
- `GenericStore` - Generic storage layer
|
|
- `Object`, `Storable` - Traits
|
|
|
|
---
|
|
|
|
## Usage in ZDFZ API
|
|
|
|
```rust
|
|
use osiris::rhai::{OsirisContext, OsirisEngineConfig, create_osiris_engine_with_config};
|
|
use osiris::store::TypeRegistry;
|
|
use std::sync::Arc;
|
|
|
|
// 1. Create type registry
|
|
let registry = TypeRegistry::new();
|
|
registry.register_type::<DigitalResident>("residents")?;
|
|
registry.register_type::<FreezoneCompany>("companies")?;
|
|
registry.register_type::<Invoice>("invoices")?;
|
|
let registry = Arc::new(registry);
|
|
|
|
// 2. Create engine config
|
|
let mut config = OsirisEngineConfig::new();
|
|
config.add_context("zdfz", "admin", "redis://localhost:6379", 1);
|
|
|
|
// 3. Create engine
|
|
let (mut engine, scope) = create_osiris_engine_with_config(config)?;
|
|
|
|
// 4. Register ZDFZ DSL functions
|
|
register_resident_api(&mut engine);
|
|
register_company_api(&mut engine);
|
|
register_invoice_api(&mut engine);
|
|
|
|
// 5. Run scripts!
|
|
engine.eval_with_scope(&mut scope, r#"
|
|
let resident = create_resident(#{
|
|
email: "test@example.com",
|
|
first_name: "John"
|
|
});
|
|
|
|
zdfz.save("residents", resident.id, resident);
|
|
"#)?;
|
|
```
|
|
|
|
---
|
|
|
|
## Benefits
|
|
|
|
✅ **Clean API** - Builder pattern for context creation
|
|
✅ **Type-Safe** - Registry ensures correct types are used
|
|
✅ **Flexible** - Applications register their own types
|
|
✅ **Proper Indexing** - Each type's `index_keys()` is called
|
|
✅ **Organized** - Engine in rhai module where it belongs
|
|
✅ **Simple Runner** - Single file, uses library code
|
|
|
|
---
|
|
|
|
**Status:** All refactoring complete and ready for use! 🚀
|