refactor: rename memory_entity→knowledge_node, knowledge graph edge→knowledge_edge
CI / CI (pull_request) Failing after 11m15s

Resolves table name collision between:
- memory_edge (provenance DAG: child_sha/parent_sha) — KEPT
- knowledge_edge (knowledge graph: source_id/target_id) — NEW NAME

Changes:
- memory_entity → knowledge_node (all .rs + migrations 003-009)
- knowledge graph memory_edge → knowledge_edge
- memory_entity_version → knowledge_node_version
- memory_edge_version → knowledge_edge_version
- Added knowledge_node + knowledge_edge to init_schema()
- Converted versioning.rs from sqlx::query_as! to runtime queries
  (avoids stale sqlx offline cache dependency)
- Fixed UUID cast: $1::UUID for String→UUID column binds
- Fixed column names: source_entity_id→source_id, target_entity_id→target_id

Production DB: knowledge_node + knowledge_edge tables created,
memory_entity VIEW points to knowledge_node for backward compat.
This commit is contained in:
2026-09-15 15:22:41 +09:00
parent b514c43d6b
commit 7d49a2aaef
36 changed files with 263 additions and 283 deletions
+32 -109
View File
@@ -1,15 +1,16 @@
use serde::{Deserialize, Serialize};
use sqlx::PgPool;
use sqlx::{PgPool, FromRow};
use uuid::Uuid;
use chrono::{DateTime, Utc};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct VersionSnapshot {
pub version_num: i32,
pub operation: String, // 'create' | 'update' | 'delete'
pub snapshot: serde_json::Value,
pub changed_at: DateTime<Utc>,
pub changed_by: String,
#[sqlx(default)]
pub fields_changed: Vec<String>,
}
@@ -40,8 +41,7 @@ impl EntityVersioningService {
/// Get all versions of an entity in descending order
pub async fn get_versions(&self, entity_id: &str) -> Result<Vec<VersionSnapshot>, sqlx::Error> {
sqlx::query_as!(
VersionSnapshot,
sqlx::query_as::<_, VersionSnapshot>(
r#"
SELECT
version_num,
@@ -49,13 +49,13 @@ impl EntityVersioningService {
snapshot,
changed_at,
changed_by,
COALESCE(fields_changed, '{}') as "fields_changed!"
FROM memory_entity_version
COALESCE(fields_changed, '{}') as fields_changed
FROM knowledge_node_version
WHERE entity_id = $1
ORDER BY version_num DESC
"#,
entity_id
)
.bind(entity_id)
.fetch_all(&self.pool)
.await
}
@@ -66,8 +66,7 @@ impl EntityVersioningService {
entity_id: &str,
version_num: i32,
) -> Result<Option<VersionSnapshot>, sqlx::Error> {
sqlx::query_as!(
VersionSnapshot,
sqlx::query_as::<_, VersionSnapshot>(
r#"
SELECT
version_num,
@@ -75,13 +74,13 @@ impl EntityVersioningService {
snapshot,
changed_at,
changed_by,
COALESCE(fields_changed, '{}') as "fields_changed!"
FROM memory_entity_version
COALESCE(fields_changed, '{}') as fields_changed
FROM knowledge_node_version
WHERE entity_id = $1 AND version_num = $2
"#,
entity_id,
version_num
)
.bind(entity_id)
.bind(version_num)
.fetch_optional(&self.pool)
.await
}
@@ -95,78 +94,7 @@ impl EntityVersioningService {
) -> Result<DiffResult, sqlx::Error> {
let from_snap = self.get_version(entity_id, from_v).await?;
let to_snap = self.get_version(entity_id, to_v).await?;
let from_obj = from_snap
.as_ref()
.and_then(|s| s.snapshot.as_object())
.map(|o| o.clone());
let to_obj = to_snap
.as_ref()
.and_then(|s| s.snapshot.as_object())
.map(|o| o.clone());
let mut added = Vec::new();
let mut removed = Vec::new();
let mut modified = Vec::new();
// Check removed and modified
if let Some(ref from) = from_obj {
for (key, from_val) in from {
if let Some(to) = &to_obj {
if let Some(to_val) = to.get(key) {
if from_val != to_val {
modified.push(DiffField {
name: key.clone(),
from_value: Some(from_val.clone()),
to_value: Some(to_val.clone()),
});
}
} else {
removed.push(DiffField {
name: key.clone(),
from_value: Some(from_val.clone()),
to_value: None,
});
}
} else {
removed.push(DiffField {
name: key.clone(),
from_value: Some(from_val.clone()),
to_value: None,
});
}
}
}
// Check added
if let Some(to) = to_obj {
for (key, to_val) in to {
if let Some(from) = &from_obj {
if !from.contains_key(&key) {
added.push(DiffField {
name: key,
from_value: None,
to_value: Some(to_val),
});
}
} else {
added.push(DiffField {
name: key,
from_value: None,
to_value: Some(to_val),
});
}
}
}
Ok(DiffResult {
from_version: from_v,
to_version: to_v,
added_fields: added,
removed_fields: removed,
modified_fields: modified,
})
compute_diff(from_snap, to_snap, from_v, to_v)
}
/// Get entity state at a point in time
@@ -175,8 +103,7 @@ impl EntityVersioningService {
entity_id: &str,
as_of: DateTime<Utc>,
) -> Result<Option<VersionSnapshot>, sqlx::Error> {
sqlx::query_as!(
VersionSnapshot,
sqlx::query_as::<_, VersionSnapshot>(
r#"
SELECT
version_num,
@@ -184,15 +111,15 @@ impl EntityVersioningService {
snapshot,
changed_at,
changed_by,
COALESCE(fields_changed, '{}') as "fields_changed!"
FROM memory_entity_version
COALESCE(fields_changed, '{}') as fields_changed
FROM knowledge_node_version
WHERE entity_id = $1 AND changed_at <= $2
ORDER BY version_num DESC
LIMIT 1
"#,
entity_id,
as_of
)
.bind(entity_id)
.bind(as_of)
.fetch_optional(&self.pool)
.await
}
@@ -210,8 +137,7 @@ impl EdgeVersioningService {
/// Get all versions of an edge
pub async fn get_versions(&self, edge_id: Uuid) -> Result<Vec<VersionSnapshot>, sqlx::Error> {
sqlx::query_as!(
VersionSnapshot,
sqlx::query_as::<_, VersionSnapshot>(
r#"
SELECT
version_num,
@@ -219,13 +145,13 @@ impl EdgeVersioningService {
snapshot,
changed_at,
changed_by,
COALESCE(fields_changed, '{}') as "fields_changed!"
FROM memory_edge_version
COALESCE(fields_changed, '{}') as fields_changed
FROM knowledge_edge_version
WHERE edge_id = $1
ORDER BY version_num DESC
"#,
edge_id
)
.bind(edge_id)
.fetch_all(&self.pool)
.await
}
@@ -237,8 +163,7 @@ impl EdgeVersioningService {
from_v: i32,
to_v: i32,
) -> Result<DiffResult, sqlx::Error> {
let from_snap = sqlx::query_as!(
VersionSnapshot,
let from_snap = sqlx::query_as::<_, VersionSnapshot>(
r#"
SELECT
version_num,
@@ -246,18 +171,17 @@ impl EdgeVersioningService {
snapshot,
changed_at,
changed_by,
COALESCE(fields_changed, '{}') as "fields_changed!"
FROM memory_edge_version
COALESCE(fields_changed, '{}') as fields_changed
FROM knowledge_edge_version
WHERE edge_id = $1 AND version_num = $2
"#,
edge_id,
from_v
)
.bind(edge_id)
.bind(from_v)
.fetch_optional(&self.pool)
.await?;
let to_snap = sqlx::query_as!(
VersionSnapshot,
let to_snap = sqlx::query_as::<_, VersionSnapshot>(
r#"
SELECT
version_num,
@@ -265,17 +189,16 @@ impl EdgeVersioningService {
snapshot,
changed_at,
changed_by,
COALESCE(fields_changed, '{}') as "fields_changed!"
FROM memory_edge_version
COALESCE(fields_changed, '{}') as fields_changed
FROM knowledge_edge_version
WHERE edge_id = $1 AND version_num = $2
"#,
edge_id,
to_v
)
.bind(edge_id)
.bind(to_v)
.fetch_optional(&self.pool)
.await?;
// Same diff logic as entities
compute_diff(from_snap, to_snap, from_v, to_v)
}
}