stripping schema nulls from stems
This commit is contained in:
@ -80,6 +80,7 @@ The Merger provides an automated, high-performance graph synchronization engine
|
||||
* **Hierarchical Table Inheritance**: The Punc system uses distributed table inheritance (e.g. `person` inherits `user` inherits `organization` inherits `entity`). The Merger splits the incoming JSON payload and performs atomic row updates across *all* relevant tables in the lineage map.
|
||||
* **The Archive Paradigm**: Data is never deleted in the Punc system. The Merger securely enforces referential integrity by toggling the `archived` Boolean flag on the base `entity` table rather than issuing SQL `DELETE` commands.
|
||||
* **Change Tracking & Reactivity**: The Merger diffs the incoming JSON against the existing database row (utilizing static, `DashMap`-cached `lk_` SELECT string templates). Every detected change is recorded into the `agreego.change` audit table, tracking the user mapping. It then natively uses `pg_notify` to broadcast a completely flat row-level diff out to the Go WebSocket server for O(1) routing.
|
||||
* **Intelligent Nested Notifications (Reactive Hydration)**: When the Merger detects that a Foreign Key column (e.g., `customer_id` on an `order`) has been explicitly modified, it automatically queries the newly pointed-to entity (e.g., `person`) and bundles its full JSON payload directly inside the parent's `pg_notify` broadcast. This guarantees that downstream caching clients (like the Dart UI) seamlessly receive the exact required subgraph to hydrate their relational widgets instantly, eliminating the need for N+1 HTTP fetches or extraneous notification lookups. This only triggers when the parent entity actively owns the relationship column and the value materially changes.
|
||||
* **Many-to-Many Graph Edge Management**: Operates seamlessly with the global `agreego.relationship` table, allowing the system to represent and merge arbitrary reified M:M relationships directionally between any two entities.
|
||||
* **Sparse Updates**: Empty JSON strings `""` are directly bound as explicit SQL `NULL` directives to clear data, whilst omitted (missing) properties skip UPDATE execution entirely, ensuring partial UI submissions do not wipe out sibling fields.
|
||||
* **Unified Return Structure**: To eliminate UI hydration race conditions and multi-user duplication, `jspg_merge` explicitly strips the response graph and returns only the root `{ "id": "uuid" }` (or an array of IDs for list insertions). External APIs can then explicitly call read APIs to fetch the resulting graph, while the UI relies 100% implicitly on the flat `pg_notify` pipeline for reactive state synchronization.
|
||||
|
||||
1020
fixtures/stems.json
1020
fixtures/stems.json
File diff suppressed because it is too large
Load Diff
@ -8,10 +8,5 @@ pub struct Stem {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub relation: Option<String>,
|
||||
|
||||
// The actual database schema node mapping for
|
||||
// O(1) jump table execution for queryer.
|
||||
//
|
||||
// Automatically skipped from `jspg_stems()` JSON payload output.
|
||||
#[serde(skip)]
|
||||
pub schema: Arc<Schema>,
|
||||
}
|
||||
|
||||
21
src/lib.rs
21
src/lib.rs
@ -121,24 +121,11 @@ pub fn jspg_stems() -> JsonB {
|
||||
|
||||
match engine_opt {
|
||||
Some(engine) => {
|
||||
let mut result_arr = Vec::new();
|
||||
for (schema_name, stems_map) in &engine.database.stems {
|
||||
let mut stems_arr = Vec::new();
|
||||
for (path_key, stem_arc) in stems_map {
|
||||
stems_arr.push(serde_json::json!({
|
||||
"path": path_key,
|
||||
"type": stem_arc.r#type,
|
||||
"relation": stem_arc.relation
|
||||
}));
|
||||
}
|
||||
result_arr.push(serde_json::json!({
|
||||
"schema": schema_name,
|
||||
"stems": stems_arr
|
||||
}));
|
||||
}
|
||||
JsonB(serde_json::to_value(result_arr).unwrap_or(Value::Array(Vec::new())))
|
||||
let stems_json = serde_json::to_value(&engine.database.stems)
|
||||
.unwrap_or(serde_json::Value::Object(serde_json::Map::new()));
|
||||
JsonB(stems_json)
|
||||
}
|
||||
None => JsonB(Value::Array(Vec::new())),
|
||||
None => JsonB(serde_json::Value::Object(serde_json::Map::new())),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user