Portable SignalQL analytics data model
Adapters map warehouse-specific schemas to this minimal logical model. Field names below are defaults; adapters may rename columns when compiling queries.
user_id and session_id links are nullable in the portable model, so event/session rows may exist without a matching parent row.
Tables
events
| Column | Type | Null | Semantics |
|---|---|---|---|
event_name | text | no | Canonical event identifier |
user_id | text | yes | Stable user key when known |
session_id | text | yes | Session bucket |
timestamp | timestamptz | no | Event time in UTC |
properties | jsonb | yes | Arbitrary payload; access rules below |
users
| Column | Type | Null | Semantics |
|---|---|---|---|
user_id | text | no | Primary key |
traits | jsonb | yes | Profile attributes |
sessions
| Column | Type | Null | Semantics |
|---|---|---|---|
session_id | text | no | Primary key |
user_id | text | yes | Owner |
started_at | timestamptz | no | Session start |
ended_at | timestamptz | yes | Optional explicit end |
JSON property access
- Dot paths refer to
propertieson events ortraitson users, e.g.properties.plan = 'pro'. - Missing keys compare false for equality filters; adapters document JSON coercion.
- Only literal comparisons are required in v0.1; nested objects use documented paths.
Mapping custom schemas
Adapters provide column maps and optional expression maps for derived fields. Required capabilities:
- Resolve
event_name,timestamp, anduser_id(or anonymous surrogate). - Expose
propertiesas JSON or map to a flat view.
Required vs optional
- Required:
events.event_name,events.timestamp; one of user linkage or anonymous handling. - Optional:
session_id,properties, fullusers/sessionstables when not used.
The sample seed dataset in this repository matches this model for tests and demos.
Graph model (v0.4)
v0.4 graph queries bind two additional logical sources, resolved through the source map (entities, edges keys; defaults entities and edges):
entities
| Column | Required | Meaning |
|---|---|---|
entity_id | yes | Stable identifier. |
kind | yes | Entity type, e.g. decision, ticket, assumption. |
properties | no | JSON payload; bare predicate names resolve here. |
updated_at | for AS OF | Version effective time (bitemporal anchor). |
version / superseded | no | Revision metadata. |
edges (relationship store)
| Column | Required | Meaning |
|---|---|---|
from_entity | yes | Source entity id. |
relationship | yes | Edge label, e.g. derived_from, supports (vocab is external). |
to_entity | yes | Target entity id. |
properties | no | JSON payload; confidence is read for lineage. |
observed_at | for AS OF | Edge effective time. |
Provenance edges — derived_from plus source/confidence — form the lineage substrate that TRACE walks. Required: entity_id, kind, and the three edge endpoint columns. updated_at/observed_at are required only when using bitemporal AS OF.
Object model (v0.5)
v0.5 Information Objects add four logical sources, resolved through the source map (objects, object_revisions, object_representations, object_derivations; defaults are the same names).
objects — one row per information object; identity is object_id, never a path.
| Column | Required | Meaning |
|---|---|---|
object_id | yes | Stable, location-independent identifier (object://<object_id>). |
type | yes | Object type, e.g. document, meeting, claim. |
title, project | no | Display title; opaque partition label. |
metadata | no | JSON payload (paths, URLs, …); other predicate names resolve here. |
created_at | yes | Creation time. |
tombstoned_at | no | When the object was withdrawn. |
object_revisions — one row per state of an object.
| Column | Required | Meaning |
|---|---|---|
object_id, rev | yes | Object and revision number (from 1). |
created_at | yes | Revision time; AS OF selects by it. |
origin, trust, validation | yes | Provenance and trust metadata. |
roles | no | Array of roles, e.g. data, instruction, secret. |
content_hash | no | Hash of the revision's content. |
object_representations — the forms of one revision.
| Column | Required | Meaning |
|---|---|---|
object_id, rev, name | yes | Which revision, and the representation name (original, summary, …). |
media_type | yes | Only text/* and application/json are packed into context bundles. |
token_estimate, estimator | no | Token count and what produced it. |
roles | no | Roles specific to this representation. |
content / content_ref, content_hash | no | Inline content, or where to fetch it. |
object_derivations — derived revision → source revision.
| Column | Required | Meaning |
|---|---|---|
from_object, from_rev | yes | The derived revision. |
relation | yes | derived_from, generated_from, extracted_from, summarized_from, or transformed_from. |
to_object, to_rev | yes | The source revision that was read (pinned). |
created_at | yes | When the derivation was recorded. |
metadata | no | JSON payload, e.g. a locator. |
A store also exposes objects to the graph sources — each revision as an entities row and each derivation as an edges row — so v0.4 graph operators work across objects and entities. See the object model spec.