| name | server-storage |
| description | @stello-ai/server 的 PG 持久化层设计决策和实现模式。触发条件:修改或引用 server 存储层。 |
Server Storage Layer — PG 持久化
相关 skill:storage-design(接口定义)、server-design(传输层)
Schema 设计决策
7 张表:users, spaces, sessions, records, session_data, session_refs, core_data
- 不需要 topology_nodes 表 — TopologyNode 从 sessions 表派生(
SELECT id, parent_id, label)
- children/refs 不存列 —
WHERE parent_id= 派生 children,JOIN session_refs 派生 refs
- session_data 统一槽位 — 不同 key 存不同语义(system_prompt / insight / memory / scope / index),避免列爆炸
- records 表共享 — session 包和 core 包各自投影字段(Message 无 metadata,TurnRecord 有)
- CASCADE 删除 — sessions ON DELETE CASCADE 级联到 records、session_data、session_refs
3 个 Storage Adapter
| Adapter | 实现接口 | 职责 |
|---|
| PgSessionStorage | SessionStorage(@stello-ai/session) | 单个 Session 数据操作(含 root,所有 Session 同构) |
| PgSessionTree | SessionTree(@stello-ai/core) | 拓扑:createSession / listRoots / 树操作 / 固化配置 |
| PgMemoryEngine | MemoryEngine(@stello-ai/core) | 核心数据读写、递归上下文组装 |
批量 digest 收集由 StelloAgent.listSessionDigests() 在应用层组合 SessionTree.listAll() + SessionStorage.getMemory/getInsight 完成,存储层不需要提供专用方法。
关键实现模式
spaceId 隔离
所有 adapter 构造时绑定 spaceId,所有 SQL 查询 WHERE space_id = $1。多租户隔离在查询层保证。
Slot 统一存储
session_data (session_id, key) 表,UPSERT 模式 ON CONFLICT (session_id, key) DO UPDATE。
两种 SessionMeta 投影
PG 存 sessions 表超集。不同 adapter 投影为不同类型:
- PgSessionStorage → @stello-ai/session 的 SessionMeta(
id / label / status / createdAt / updatedAt)
- PgSessionTree → @stello-ai/core 的 SessionMeta(含 scope / turnCount / lastActiveAt)+ TopologyNode(纯树结构)
递归 CTE
getAncestors、getAllDescendantIds、assembleContext 都用 WITH RECURSIVE 遍历树结构。
事务支持
PgSessionStorage.transaction() 通过类型判断区分 Pool 与 PoolClient。Pool 时获取独占 client 开事务,PoolClient 时直接执行。