No-Code SaaS Automation Platform  ·  View 11 of 21  ·  Data

Data Model

Eight entities. The composite key on step_attempt is where exactly-once visible effect actually lives.

Editable source SVG draw.io All views
workspace workspace_id PK plan residency_region retention_policy connector_version connector_id PK version PK replay_class rate_limit_profile eol_date connection connection_id PK workspace_id FK connector_id FK scopes state automation_version automation_id PK version PK workspace_id FK trigger_ref published_at credential credential_id PK connection_id FK ciphertext key_id expires_at trigger_event event_id PK connection_id FK provider_event_id payload_ref received_at run run_id PK event_id FK automation_id FK version state step_attempt run_id PK step_id PK attempt PK effect_key outcome 1 : N 1 : N 1 : 1 1 : N 1 : N 1 : 1 1 : N Data Model — Core Entities effect_key is derived from (run_id, step_id, logical attempt) - the uniqueness that keeps a retry from duplicating an effect. v 1.0 · owner Integration Platform Architecture · date 2026-10

Decisions

  • step_attempt is keyed (run_id, step_id, attempt) and carries effect_key, derived from the run, the step and the logical attempt. A retry reuses the key; a replay mints a new logical attempt. That distinction is the whole difference between 'try again' and 'do it again'.
  • automation_version is an entity rather than a mutable automation row: a run in flight completes under the version it started with, so the definition must be immutable and addressable.
  • credential is separated from connection so the ciphertext and key reference live in the custody account while the connection's state and scopes stay queryable by the control plane.
  • connector_version carries replay_class, making replay safety a stored, versioned property rather than something inferred at call time.

Assumptions

  • trigger_event holds a payload_ref rather than the payload, so the 30-day retention and residency rules apply to object storage rather than to the index.
  • workspace carries residency_region, and it is immutable once set.

Deliberately omitted

  • Quota counters, run leases and subscription state are not modelled here: they are operational state with their own lifecycle, shown as zones in view 10.