- add server-side .env.local OpenAI key management for the open-source app - route AI features through the preferred local key path and lazy-load embed recovery - rewrite README and docs for current MCP setup, schema, and fully-local guidance Generated with Claude Code
2.3 KiB
2.3 KiB
RA-H Schema
Core Tables
nodes
idtitledescriptionsourcelinkmetadatachunk_statusevent_datecontext_idnullable FK tocontexts.idcreated_atupdated_at
contexts
idnamedescriptioniconcreated_atupdated_at
edges
idfrom_node_idto_node_idexplanationcontextsourcecreated_at
chunks
idnode_idchunk_idxtextembedding_typemetadatacreated_at
dimension_migration_snapshots
- Stores one-time snapshots of legacy dimension data before dropping the old tables.
- Exists for auditability and migration verification only.
Search / Retrieval
nodes_ftsindexes title, description, and source for full-text lookup.chunks_ftsindexes chunk text.vec_nodesstores node-level vectors.vec_chunksstores chunk-level vectors.
Full-text search and vector search are separate surfaces:
- FTS uses
nodes_fts/chunks_fts - semantic/vector retrieval uses
vec_nodes/vec_chunks - retrieval may combine them, but docs should not blur them into one surface
Embedding Lifecycle
nodes.sourceis the canonical long-form field for chunking and chunk embeddings.- changing
nodes.sourceshould return the node to the app-owned chunk pipeline - standalone MCP can write
nodes.source, but it does not directly create chunks or vector rows - node-level embeddings and chunk embeddings are separate runtime surfaces
- integrity/degraded-mode behavior matters enough that docs should describe these surfaces honestly
Important Constraints
dimensionsandnode_dimensionsare no longer canonical tables.- New installs should never create them.
- Existing installs migrate by snapshotting old dimension data, then dropping the legacy tables.
contextsare optional.nodes.context_idmust allowNULL.
Common Queries
Nodes in a context:
SELECT *
FROM nodes
WHERE context_id = ?
ORDER BY updated_at DESC;
Most connected nodes:
SELECT n.id, n.title, COUNT(DISTINCT e.id) AS edge_count
FROM nodes n
LEFT JOIN edges e ON (e.from_node_id = n.id OR e.to_node_id = n.id)
GROUP BY n.id
ORDER BY edge_count DESC, n.updated_at DESC
LIMIT 10;
Recently updated nodes:
SELECT id, title, updated_at
FROM nodes
ORDER BY updated_at DESC
LIMIT 25;