Add three open questions (OQ-17, OQ-18, OQ-19) covering attribute query strategy, CRUD generation approach, and storage-operations bridge placement. Create ADR-033 recording the v1 decision: JSON path queries for attributes with hand-written CRUD for static tables. Expand forward-look.md with Repository Layer Strategy section analyzing three approaches (JSON path, native columns via dbtype, hybrid) and their implications for the metagraph pattern. Add drizzle-graphql and dbtype from-dbtype comparison showing neither handles dynamic schema-as-data. Update overview.md with dbtype/ujsx in the dependency diagram, expanded ecosystem context in the bridging pattern section, and new open questions. Align open-questions.md: resolve OQ-17 and OQ-18 for v1 (ADR-033), add OQ-19 as open, update summary counts and ADR impact table.
93 lines
6.6 KiB
Markdown
93 lines
6.6 KiB
Markdown
---
|
|
status: reviewed
|
|
last_updated: 2026-05-30
|
|
---
|
|
|
|
# @alkdev/storage Architecture
|
|
|
|
Typed graph storage with dual database hosts. Deno-first, published via JSR.
|
|
|
|
## Current State
|
|
|
|
Storage has Phase 1-3 of the metagraph implementation complete: Metagraph Module, bridge functions, reference graph type Modules (CallGraph, SecretGraph), and crypto utility. Phase 4 (graphology bridge) is pending. The repository/CRUD layer, PostgreSQL host, and additional graph types remain to be implemented.
|
|
|
|
## Architecture Documents
|
|
|
|
| Document | Content | Status |
|
|
|----------|---------|--------|
|
|
| [overview.md](overview.md) | Package purpose, exports, dependencies, ecosystem integration | reviewed |
|
|
| [metagraph-module.md](metagraph-module.md) | TypeBox Module type system, bridge functions, implementation path | reviewed |
|
|
| [sqlite-host.md](sqlite-host.md) | SQLite tables, relations, client factory, PG porting notes | reviewed |
|
|
| [schema-evolution.md](schema-evolution.md) | Value.Diff/Cast/Patch for schema migration, version strategy | reviewed |
|
|
| [encrypted-data.md](encrypted-data.md) | Crypto utility, encrypted node type, key management | reviewed |
|
|
| [forward-look.md](forward-look.md) | Pointers, dbtype, ujsx IR (conceptual, post-v1) | draft |
|
|
|
|
### Design Decisions
|
|
|
|
| ADR | Decision | Status |
|
|
|-----|----------|--------|
|
|
| [001](decisions/001-deno-first-jsr-publishes.md) | Deno-first, JSR publishes, npm comes free | Accepted |
|
|
| [002](decisions/002-metagraph-over-domain-tables.md) | Metagraph pattern over domain-specific tables | Accepted |
|
|
| [003](decisions/003-typebox-module-as-api-surface.md) | TypeBox Module as the graph type definition API surface | Accepted |
|
|
| [004](decisions/004-injectable-clients-no-side-effects.md) | Injectable clients, no module-level side effects | Accepted |
|
|
| [005](decisions/005-drizzle-plus-typebox-via-drizzlebox.md) | Drizzle + TypeBox via drizzlebox | Accepted |
|
|
| [006](decisions/006-enum-pattern-as-const-objects.md) | `as const` objects, not TypeScript enums | Accepted |
|
|
| [007](decisions/007-no-comments-in-code.md) | No comments in code | Accepted |
|
|
| [008](decisions/008-common-columns-pattern.md) | Common columns pattern | Accepted |
|
|
| [009](decisions/009-typebox-module-replaces-schemabuilder.md) | TypeBox Module replaces the SchemaBuilder | Accepted |
|
|
| [010](decisions/010-metagraph-import-for-same-package.md) | Metagraph.Import() for same-package Modules | Accepted |
|
|
| [011](decisions/011-config-as-module-entry-with-literal-values.md) | Config as Module entry with Literal values | Accepted |
|
|
| [012](decisions/012-node-edge-attributes-as-module-entries.md) | Node/edge attribute schemas are Module entries | Accepted |
|
|
| [013](decisions/013-storage-produces-graphology-format.md) | Storage produces graphology format, flowgraph consumes it | Accepted |
|
|
| [014](decisions/014-dereferenced-entry-schemas.md) | Repository stores dereferenced entry schemas | Accepted |
|
|
| [015](decisions/015-edge-constraints-as-named-entries.md) | Edge type constraints as named Module entries | Accepted |
|
|
| [016](decisions/016-naming-convention-for-module-entries.md) | Naming convention for Module entries | Accepted |
|
|
| [017](decisions/017-pointer-abstraction-is-forward-looking.md) | Pointer abstraction is forward-looking, not v1 | Accepted |
|
|
| [018](decisions/018-dbtype-integration-is-post-v1.md) | dbtype integration is post-v1 | Accepted |
|
|
| [019](decisions/019-json-text-for-schema-columns.md) | JSON text for schema columns in SQLite | Accepted |
|
|
| [020](decisions/020-no-nodetypeid-on-nodes.md) | No nodeTypeId on nodes | Accepted |
|
|
| [021](decisions/021-edge-identity-uses-consumer-keys.md) | Edge identity uses consumer-defined keys | Accepted |
|
|
| [022](decisions/022-composite-fks-for-node-references.md) | Composite foreign keys for node references | Accepted |
|
|
| [023](decisions/023-per-attribute-encryption.md) | Per-attribute encryption, not per-node | Accepted |
|
|
| [024](decisions/024-encrypted-data-as-node-type.md) | Encrypted data as node type, not standalone table | Accepted |
|
|
| [025](decisions/025-password-based-encryption-pbkdf2.md) | Password-based encryption via PBKDF2 | Accepted |
|
|
| [026](decisions/026-application-managed-key-ring.md) | Application-managed key ring | Accepted |
|
|
| [027](decisions/027-no-key-rotation-utility.md) | No key rotation utility in this package | Accepted |
|
|
| [028](decisions/028-additive-only-with-cast-migration.md) | Additive-only for v1, Cast migration when needed | Accepted |
|
|
| [029](decisions/029-version-as-breaking-change-signal.md) | Version as a coarse-grained breaking-change signal | Accepted |
|
|
| [030](decisions/030-schema-change-detection-via-diff.md) | Schema change detection via Value.Diff | Accepted |
|
|
| [031](decisions/031-moduletodbschema-for-updates.md) | moduleToDbSchema() for schema updates | Accepted |
|
|
| [032](decisions/032-single-author-not-crdt.md) | Single-author model, not CRDT | Accepted |
|
|
| [033](decisions/033-json-path-queries-for-v1.md) | JSON path queries and hand-written CRUD for v1 | Accepted |
|
|
|
|
### Open Questions
|
|
|
|
All unresolved design questions are tracked in [open-questions.md](open-questions.md), organized by theme with cross-references between related questions.
|
|
|
|
## Document Lifecycle
|
|
|
|
Architecture documents use YAML frontmatter with `status` and `last_updated` fields:
|
|
|
|
```yaml
|
|
---
|
|
status: draft | reviewed | stable | deprecated
|
|
last_updated: YYYY-MM-DD
|
|
---
|
|
```
|
|
|
|
| Status | Meaning | Transitions |
|
|
|--------|---------|-------------|
|
|
| `draft` | Under active development. Content may change significantly. Implementation should not start until the document reaches `reviewed`. | → `reviewed` when all open questions are resolved and cross-cutting issues are addressed. |
|
|
| `reviewed` | Architecture is final and reviewed. Implementation may begin. API contracts are specified but not yet verified by tests. Changes require a review cycle. | → `stable` when implementation is complete and API contracts are verified by tests. → `draft` if a fundamental redesign is needed. |
|
|
| `stable` | API contracts are locked and verified by tests. Changes require a review cycle and may warrant an ADR. | → `deprecated` when superseded. |
|
|
| `deprecated` | Superseded by another document. Kept for reference. | Removed when no longer referenced. |
|
|
|
|
ADR documents use a separate `Status` field in their body: `Proposed`, `Accepted`, `Deprecated`, or `Superseded`. ADRs never revert from `Accepted`.
|
|
|
|
## References
|
|
|
|
- Source: `src/`
|
|
- AGENTS.md: `/workspace/@alkdev/storage/AGENTS.md`
|
|
- Flowgraph architecture (pattern reference): `/workspace/@alkdev/flowgraph/docs/architecture/`
|
|
- ujsx architecture: `/workspace/@alkdev/ujsx/docs/architecture/`
|
|
- Operations architecture: `/workspace/@alkdev/operations/docs/architecture/` |