Files
osiris/REFACTORING_COMPLETE.md
Timur Gordon e04012c8c0 Refactor Rhai integration with context-based execution and type registry
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
2025-10-28 03:33:39 +01:00

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! 🚀