LearnYour First State

Your First State (Entity)

We are building the concert app — users follow artists, artists announce shows, and a query returns upcoming shows for followed artists. Every getting-started tutorial walks through one layer of this same application.

State defines the entity types — one snapshot per (stream, entity_id). Everything else references these types.


Set up the project

Scaffold the app with the CLI — do this once before the layer tutorials (or before the Quickstart):

causet init

When prompted:

PromptChoose
Project nameconcert-app (or any name)
TemplateConcert app — follow artists, announce shows, query upcoming shows
cd concert-app

The template creates app.causet, starter files for every DSL layer, and a README. The tutorials below explain what each file does — you can follow along in the project you just created.

# app.causet  (created by the template)
dsl_version: 1
app: concert_app
 
includes:
  states:        [./states/**/*.state.causet]
  events:        [./events/**/*.events.causet]
  actions:       [./actions/**/*.actions.causet]
  projections:   [./projections/**/*.projections.causet]
  queries:       [./queries/**/*.queries.causet]
  relationships: [./relationships/**/*.relationships.causet]

Prerequisites: Install Causet — CLI installed and authenticated against Causet Cloud.


What you define

FieldPurpose
entity_keyWhich payload field identifies an instance (e.g. user_id)
fieldsTyped columns on the entity snapshot
defaultInitial value when the entity is first created

Streams are derived from the state name — user becomes user_stream at runtime.

Open the state files the template created under states/:


User entity

# states/user.state.causet
state:
  user:
    entity_key: user_id
    fields:
      - name: username
        type: string
        default: ""
      - name: following_count
        type: int
        default: 0

Artist entity

# states/artist.state.causet
state:
  artist:
    entity_key: artist_id
    fields:
      - name: name
        type: string
        default: ""
      - name: follower_count
        type: int
        default: 0

Each instance is addressed as (stream, entity_id) — e.g. user user-1 on user_stream, artist artist-pearl-jam on artist_stream.


How state is used at runtime

  1. An intent targets (stream, entity_id) — the runtime loads the current snapshot.
  2. Core rules mutate fields (set, add, …).
  3. The committed snapshot is stored in PostgreSQL.
  4. Events emitted during the intent reference the entity via entity_expr.

Entity snapshots are the write side. Projections are separate read models.


Verify entity state

After deploying and running intents:

causet inspect entity user-1 \
  --fork main \
  --stream user_stream

Concert app so far

After causet initConcert app, your project includes:

concert-app/
  app.causet
  states/
    user.state.causet
    artist.state.causet
  … (events, actions, projections, queries, relationships — covered in later tutorials)

This tutorial focuses on states/.


Common mistakes

Wrong entity_key. Must match the field callers use as the entity ID in intents.

Modeling read tables as state. Use projections for list views and joins — not entity snapshots.


Next steps