docs: restructure architecture docs to flowgraph pattern
- Create decisions/ directory with 32 numbered ADRs (ADR-001 through ADR-032) extracted from inline DD/SD/ED/SE decision sections - Create open-questions.md with 16 OQs organized by theme, cross-referenced to ADRs, with status tracking (resolved/open) - Create README.md as architecture index with doc table, ADR table, and lifecycle status definitions (draft/reviewed/stable/deprecated) - Replace inline decision sections in all spec docs with ADR reference tables - Replace inline open questions with OQ references to centralized tracker - Update frontmatter: metagraph-module.md, overview.md, sqlite-host.md → reviewed; schema-evolution.md and encrypted-data.md remain draft - DD1-DD10 → ADR-009 through ADR-018 - D1-D8 → ADR-001 through ADR-008 - SD1-SD5 → ADR-019 through ADR-023 (SD5 folded into ADR-006/008) - ED1-ED5 → ADR-023 through ADR-027 - SE1-SE5 → ADR-028 through ADR-032
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
status: draft
|
||||
last_updated: 2026-05-28
|
||||
status: reviewed
|
||||
last_updated: 2026-05-29
|
||||
---
|
||||
|
||||
# SQLite Host
|
||||
@@ -260,53 +260,16 @@ Drizzle database instance with the full schema attached. This enables:
|
||||
|
||||
## Design Decisions
|
||||
|
||||
### SD1: JSON text vs. JSONB in SQLite
|
||||
All design decisions are documented as ADRs in [decisions/](decisions/).
|
||||
|
||||
SQLite stores JSON as `text` with `{ mode: "json" }`. PostgreSQL uses native
|
||||
`jsonb`. This means:
|
||||
|
||||
- SQLite cannot query inside JSON columns efficiently (no GIN indexes)
|
||||
- SQLite JSON validation relies on application-level checks (TypeBox schemas)
|
||||
- PostgreSQL will get queryability benefits for JSON columns
|
||||
|
||||
The trade-off: SQLite is for spokes (local, infrequent queries), PostgreSQL is
|
||||
for the hub (frequent, complex queries).
|
||||
|
||||
### SD2: No `nodeTypeId` on nodes
|
||||
|
||||
Nodes don't carry a direct FK to `node_types`. The node type is enforced at the
|
||||
application layer. Reasons:
|
||||
|
||||
- Graph type schemas define which node types are valid. Adding a FK would
|
||||
duplicate this constraint.
|
||||
- Node types can evolve (schemas can change) without requiring node row updates.
|
||||
- The repository layer validates node attributes against the appropriate node
|
||||
type schema before insertion.
|
||||
|
||||
This may change if query performance requires filtering nodes by type. A
|
||||
`nodeTypeId` column can be added as a denormalized index.
|
||||
|
||||
### SD3: Edge identity uses consumer-defined keys
|
||||
|
||||
Edges use `(graphId, key)` as their unique identity. The `key` is
|
||||
consumer-defined, matching the metagraph model where consumers control
|
||||
identifiers. For anonymous edges (common in simple graphs), `key` can be
|
||||
auto-generated.
|
||||
|
||||
### SD4: Composite foreign keys for node references
|
||||
|
||||
Edges reference nodes via composite FKs:
|
||||
`(graphId, sourceNodeKey) → (nodes.graphId, nodes.key)`. This ensures
|
||||
referential integrity within a graph and cascades node deletions to connected
|
||||
edges.
|
||||
|
||||
### SD5: Enum pattern — `as const` objects, not TypeScript enums
|
||||
|
||||
All enumerations use the `as const` object pattern (e.g.,
|
||||
`GRAPH_STATUS = { Active: "active", ... } as const`) rather than TypeScript
|
||||
`enum`. This matches the `ACTOR_TYPE` pattern in `common.ts` and avoids JSR
|
||||
slow-type issues. The TypeBox schema is a `Type.Union` of `Type.Literal` values
|
||||
derived from the object.
|
||||
| ADR | Decision | Summary |
|
||||
|-----|----------|---------|
|
||||
| [019](decisions/019-json-text-for-schema-columns.md) | JSON text for schema columns in SQLite | SQLite uses `text` with JSON mode; application-level validation |
|
||||
| [020](decisions/020-no-nodetypeid-on-nodes.md) | No nodeTypeId on nodes | Node type enforced at application layer, not via FK |
|
||||
| [021](decisions/021-edge-identity-uses-consumer-keys.md) | Edge identity uses consumer-defined keys | `(graphId, key)` as unique identity within a graph |
|
||||
| [022](decisions/022-composite-fks-for-node-references.md) | Composite foreign keys for node references | Edges reference `(graphId, sourceNodeKey) → (nodes.graphId, nodes.key)` |
|
||||
| [006](decisions/006-enum-pattern-as-const-objects.md) | `as const` objects, not TypeScript enums | `GRAPH_STATUS`, `ACTOR_TYPE` use const objects; TypeBox uses Literal unions |
|
||||
| [008](decisions/008-common-columns-pattern.md) | Common columns pattern | `id`, `metadata`, `createdAt`, `updatedAt` on every table |
|
||||
|
||||
## Metadata Convention
|
||||
|
||||
|
||||
Reference in New Issue
Block a user