Database Reference

This page lists Pulse's domain tables. All tables live in your own Supabase project — not ARK's. RLS is enabled on every table.

Shared platform tables

  • profiles — user metadata and timezone.
  • workspaces — tenant boundary.
  • workspace_members — user ↔ workspace with role.

Pulse domain tables

teams

ColumnTypeNotes
iduuid PK
workspace_iduuid FK → workspaces
nametext
digest_locationjsonb{channel: "slack|comms|email", target: "..."}.
timezone_defaulttextFallback when users don't have one set.
created_attimestamptz

team_members

ColumnTypeNotes
team_iduuid FK → teams
user_iduuid FK → auth.users
roletextlead, member.

checkins

Recurring standups.

ColumnTypeNotes
iduuid PK
team_iduuid FK → teams
nametext
schedulejsonbrrule/CRON + working-hours config.
is_enabledbool
response_window_hoursintDefault 4.
digest_schedulejsonbWhen to post the digest.
delivery_channel_defaulttext
created_byuuid FK → auth.users

checkin_questions

ColumnTypeNotes
iduuid PK
checkin_iduuid FK → checkins
positionint
typetextSee Standups.
prompttext
configjsonbType-specific settings.
conditionsjsonbBranching logic.

surveys

One-off or recurring surveys.

ColumnTypeNotes
iduuid PK
workspace_iduuid FK → workspaces
titletext
kindtextsurvey, poll, enps, retro, postmortem.
is_anonymousbool
schedulejsonbNull for one-off; rrule for recurring.
opens_at, closes_attimestamptz
created_byuuid FK → auth.users

survey_questions

Same shape as checkin_questions but tied to survey_id.

responses

Answers to checkin or survey questions.

ColumnTypeNotes
iduuid PK
workspace_iduuid FK → workspaces
source_kindtextcheckin, survey, poll.
source_iduuidcheckin_id or survey_id.
question_iduuidcheckin_questions.id or survey_questions.id.
user_iduuid FK → auth.usersNull for anonymous.
answerjsonbType-specific payload.
submitted_attimestamptz
delivery_channeltextHow they answered.

digests

Compiled digest instances.

ColumnTypeNotes
iduuid PK
checkin_iduuid FK → checkinsNull for survey digests.
survey_iduuid FK → surveysNull for checkin digests.
datedateThe day covered.
contenttextRendered markdown.
delivered_attimestamptz
delivery_targetjsonbChannel + target.

reminders

ColumnTypeNotes
iduuid PK
workspace_iduuid FK → workspaces
creator_iduuid FK → auth.users
target_kindtextself, user, team.
target_iduuid
messagetext
schedulejsonbrrule/CRON + working-hours.
delivery_channeltext
next_fire_attimestamptzUpdated after each fire.
is_enabledbool

reminder_events

Audit log of reminder fires, snoozes, and acks.

slack_installations

One row per connected Slack workspace.

ColumnTypeNotes
iduuid PK
workspace_iduuid FK → workspaces
slack_team_idtext
access_tokentextEncrypted at rest via Supabase Vault.
bot_user_idtext
scopestext[]
installed_attimestamptz

slack_user_mappings

ColumnTypeNotes
slack_installation_iduuid FK → slack_installations
slack_user_idtext
user_iduuid FK → auth.usersOverride mapping.

scheduler_runs

Audit log for pulse-scheduler fires.

Relationships at a glance

workspaces
 ├─ teams
 │   ├─ team_members
 │   └─ checkins
 │       ├─ checkin_questions
 │       └─ digests
 ├─ surveys
 │   └─ survey_questions
 ├─ responses (polymorphic on source_kind)
 ├─ reminders
 │   └─ reminder_events
 └─ slack_installations
     └─ slack_user_mappings

RLS summary

  • teams, checkins, surveys: workspace-scoped.
  • responses: workspace-scoped. For is_anonymous=true rows, even admins can only read aggregated counts via views — individual rows are blocked by policy.
  • reminders: workspace-scoped. Users see their own creations plus reminders targeting them.
  • slack_installations: admin-only read.
  • The scheduler Edge Function uses the service-role client.

Anonymity guarantee

For anonymous responses, user_id is NULL by construction — no update can set it. A CHECK constraint and a dedicated RLS policy enforce this at the database layer:

create policy "anonymous_responses_stay_anonymous"
  on responses for update
  using (false)
  with check (
    (user_id is null) = (coalesce(
      (select is_anonymous from surveys where id = responses.source_id),
      false
    ))
  );