Pre-1.0. Not intended for public use yet. The API is subject to undocumented change, and these pages may already be wrong about it.

Skip to content

Schema ​

Introduction ​

Storyfeed's migrations create nine tables. Publish them with storyfeed:install or the following command:

bash
php artisan vendor:publish --tag=storyfeed-migrations

Set table names in Configuration. The migrations include indexes for feed queries. They declare no foreign key constraints: the keys below are the ones Storyfeed joins on. Storage Architecture shows which rows a publish writes and how a feed is retrieved from them.

Tables at a Glance ​

The 9 tables Storyfeed creates, and how they reference each othersolid: an id column Storyfeed joins on · dashed: a morph reference, or a keyheld in another column · no foreign key constraints are declaredbatch rows: hash = feed_batches.uidfeed_activitiesidPKuidULID · uniqueverbindexcached_{role}_idsnapshot × 7{role}_type, {role}_idmorph × 7datajsonpublished_attimestamp(6)created_at, updated_atdeleted_atsoft delete(published_at, id)({role}_type, {role}_id, published_at, id) actor, object, target, contextfeed_snapshotsidPKmodel_type, model_iduniquelabeldata, bodyjsoncontent, media_typeattributed_toshapeindexsource_updated_atmetajsonfeed_partiesidPKkeyuniquename, typedatajsonfeed_tombstonesidPKmodel_type, model_iduniquerestorable, approximatebooldeleted_at, labelmetajsonfeed_groupingsidPKactivity_id→ activitybucketaxis namehashgroup keywinnerbool or nullunique (activity_id, bucket)(bucket, hash)(winner, bucket, hash)feed_participantsidPKactivity_id→ activityroleentity_type, entity_idpublished_atcopiedunique (activity_id, role)(entity_type, entity_id, published_at, activity_id)feed_batchesidPKuidULID · uniqueactor_type, actor_idopened_at, closes_atclosed_atnull = openactivities_count(actor_type, actor_id, closed_at)(closed_at, closes_at)feed_batch_locksactor_type, actor_idPKopen_batchesjsonlocked_atfeed_metakeyuniquevaluesync_token

Each role is stored as a morph pair, {role}_type and {role}_id, holding the model's morph alias and key. Next to it, cached_{role}_id points at the entity's snapshot.

Activity Storage ​

feed_activities ​

Stores one record per activity. deleteFromFeed() soft-deletes these records. The uid ULID becomes the payload's id. Role columns store morph aliases; removing or changing an alias leaves affected roles unresolved.

ColumnTypeAttributesPurpose
idbigint, incrementsPKPrimary key.
uiduliduniqueThe activity's public identifier, the payload's id.
verbstring(255)indexThe verb, as a plain string.
actor_typestring(255)nullableThe actor's morph alias. Null when no actor is recorded.
actor_idunsigned bigintnullableThe actor's key.
object_typestring(255)nullableThe object's morph alias.
object_idunsigned bigintnullableThe object's key.
target_typestring(255)nullableThe target's morph alias.
target_idunsigned bigintnullableThe target's key.
context_typestring(255)nullableThe context's morph alias.
context_idunsigned bigintnullableThe context's key.
cached_actor_idunsigned bigintindex, nullableThe actor's row in feed_snapshots.
cached_object_idunsigned bigintindex, nullableThe object's row in feed_snapshots.
cached_target_idunsigned bigintindex, nullableThe target's row in feed_snapshots.
cached_context_idunsigned bigintindex, nullableThe context's row in feed_snapshots.
datajsonnullableThe values passed to data().
published_attimestamp(6)nullableWhen the activity happened. The feed orders by it, and only shows activities whose time has come.
created_attimestamp(6)nullableWhen the row was written.
updated_attimestamp(6)nullableWhen the row last changed.
deleted_attimestamp(6)nullableSet when an activity is soft-deleted, by deleteFromFeed() for example. Soft-deleted activities are not shown.
origin_typestring(255)nullableThe origin's morph alias.
origin_idunsigned bigintnullableThe origin's key.
cached_origin_idunsigned bigintnullableThe origin's row in feed_snapshots.
result_typestring(255)nullableThe result's morph alias.
result_idunsigned bigintnullableThe result's key.
cached_result_idunsigned bigintnullableThe result's row in feed_snapshots.
instrument_typestring(255)nullableThe instrument's morph alias.
instrument_idunsigned bigintnullableThe instrument's key.
cached_instrument_idunsigned bigintnullableThe instrument's row in feed_snapshots.
IndexColumns
indexactor_type, actor_id
indexobject_type, object_id
indextarget_type, target_id
indexcontext_type, context_id
indexpublished_at, id
indexactor_type, actor_id, published_at, id
indexobject_type, object_id, published_at, id
indextarget_type, target_id, published_at, id
indexcontext_type, context_id, published_at, id
indexorigin_type, origin_id
indexresult_type, result_id
indexinstrument_type, instrument_id

feed_snapshots ​

Stores each model's label, data, and bodies from toFeed(). Feed retrieval uses these snapshots to resolve entity labels and links. storyfeed:trickle creates and refreshes snapshots; storyfeed:rebuild rebuilds them. Model keys are unsigned big integers; UUID keys are not supported.

ColumnTypeAttributesPurpose
idbigint, incrementsPKPrimary key. Activities point here through cached_{role}_id.
model_typestring(255)The entity's morph alias.
model_idunsigned bigintThe entity's key.
labelstring(255)nullableThe label from toFeed().
componentstring(255)nullableNot written by Storyfeed.
datajsonnullableThe data from toFeed().
shapestring(40)nullableA fingerprint of the toFeed() output's structure. storyfeed:trickle refreshes rows whose fingerprint no longer matches.
created_attimestampnullableWhen the snapshot was first written.
updated_attimestampnullableWhen the snapshot was last written.
contenttextnullableThe entity's authored text, from toFeed().
media_typetextnullableThe encoding of content.
attributed_totextnullableThe entity's author IRI, from toFeed().
bodyjsonnullableThe entity's bodies, from toFeed().
source_updated_atdatetime(6)nullableThe model's updated_at when the snapshot was taken, in UTC. Older writes are rejected only when both source timestamps are known; an incoming unknown timestamp is accepted and clears this watermark.
metajsonnullableThe model's route key, when it differs from the primary key.
IndexColumns
uniquemodel_type, model_id
indexmodel_type, shape

Grouping and Batching ​

feed_groupings ​

Stores candidate groups and the selected axis for each activity. Rebuild it with storyfeed:curate --rehash.

ColumnTypeAttributesPurpose
idbigint, incrementsPKPrimary key.
activity_idunsigned bigintindexThe activity this row places in a group.
hashstring(255)The group's key on this axis. Activities sharing a bucket and hash form one group.
bucketstring(255)nullableThe axis: actors, targets, object, repeat, a summary.* period, batch or composite.
winnerbooleannullableTrue on the row curation chose for live(). Null on rows that are never curated.
created_attimestampnullableWhen the row was written.
updated_attimestampnullableWhen the row last changed.
IndexColumns
uniqueactivity_id, bucket
indexbucket, hash
indexwinner, bucket, hash

feed_batches ​

Stores an actor's activities as batches, open until the configured window has elapsed.

The meta column holds application metadata. Storyfeed has no dedicated batch-metadata setter; an application that needs it can load the configured batch Eloquent model and update its meta array directly. The model casts the column to an array. When the batch closes, BatchClosed listeners receive a frozen copy of this metadata in the batch snapshot's meta field.

ColumnTypeAttributesPurpose
idbigint, incrementsPKPrimary key.
uiduliduniqueThe batch's identifier. A batch grouping row's hash holds it.
actor_typestring(255)nullableThe actor's morph alias.
actor_idunsigned bigintnullableThe actor's key.
opened_attimestampThe published_at of the batch's first activity.
closed_attimestampindex, nullableWhen the batch closed. Null while it is open.
activities_countunsigned intdefault 0How many activities joined the batch.
last_activity_attimestampnullableThe latest published_at among its activities.
closes_attimestampnullableWhen the batch ends. Each activity moves it to its own published_at plus its verb's window, never earlier.
metajsonnullableMetadata about the batch, kept without adding a column.
created_attimestampnullableWhen the row was written.
updated_attimestampnullableWhen the row last changed.
IndexColumns
indexactor_type, actor_id
indexactor_type, actor_id, closed_at
indexclosed_at, closes_at

feed_batch_locks ​

Stores one lock per batched actor so concurrent publications join the same batch.

ColumnTypeAttributesPurpose
actor_typestring(255)The actor's morph alias.
actor_idstring(255)The actor's key, as a string.
open_batchesjsonnullableThe ids of the actor's open batches.
locked_attimestampnullableWhen a publish last locked the row.
IndexColumns
primary keyactor_type, actor_id

Participants ​

feed_parties ​

Named participants with no model in your app.

ColumnTypeAttributesPurpose
idbigint, incrementsPKPrimary key.
keystring(255)uniqueThe party's name as a slug, unless a key is given.
namestring(255)The party's label in the feed.
typestring(255)default 'Service'The party's Activity Streams type.
datajsonnullableThe data given to Party::make().
created_attimestampnullableWhen the party was created.
updated_attimestampnullableWhen the party last changed.

feed_participants ​

Indexes each activity's filled roles for involving() and $model->storyfeed() queries. Rebuild it with storyfeed:participants.

ColumnTypeAttributesPurpose
idbigint, incrementsPKPrimary key.
activity_idunsigned bigintThe activity.
rolestring(20)Which role the entity fills: actor, object, target, context, origin, result or instrument.
entity_typestring(255)The entity's morph alias.
entity_idstring(255)The entity's key, as a string.
published_attimestamp(6)nullableCopied from the activity. The entity index narrows matching activity IDs for involving(); final ordering is on the outer activity query.
created_attimestampnullableWhen the row was written.
updated_attimestampnullableWhen the row last changed.
IndexColumns
uniqueactivity_id, role
indexentity_type, entity_id, published_at, activity_id

Deletion and Metadata ​

feed_tombstones ​

Stores a tombstone for each deleted model, referenced by its activities. The alias is always storyfeed.tombstone, regardless of the morph map. See Deleted Models.

The meta column holds application metadata. Neither the public tombstone entry point nor PendingTombstone provides a metadata setter. Applications can update meta directly on the configured tombstone Eloquent model, which casts the column to an array. This is an application-owned model write, not an option on the deletion declaration.

ColumnTypeAttributesPurpose
idbigint, incrementsPKPrimary key. Activities point at a tombstone with the storyfeed.tombstone alias.
model_typestring(255)The deleted model's morph alias.
model_idstring(255)The deleted model's key, as a string.
restorablebooleandefault falseTrue while the model is soft-deleted and can come back.
approximatebooleandefault falseTrue when storyfeed:trickle found the deletion, so deleted_at is when it was found.
deleted_attimestampnullableWhen the model was deleted.
labelstring(255)nullableThe label kept for the deleted model, when it keeps one.
metajsonnullableMetadata about the deletion, kept without adding a column.
created_attimestampnullableWhen the tombstone was created.
updated_attimestampnullableWhen the tombstone last changed.
IndexColumns
uniquemodel_type, model_id

feed_meta ​

Stores Storyfeed metadata, including the sync token.

ColumnTypeAttributesPurpose
idbigint, incrementsPKPrimary key.
keystring(255)uniquesync_token, trickle cursors, or maintenance:curate:<ULID> / maintenance:trickle:<ULID> entries in bounded maintenance-run history.
valuestring(255)The value; maintenance-run entries contain JSON counters for that completed run.
created_attimestampnullableWhen the row was written.
updated_attimestampnullableWhen the row last changed.

Released under the MIT License.