AnyBio
Components

bio-checkin

<bio-checkin>

A patient-reported outcome (PRO) check-in widget that presents a step-by-step questionnaire and submits responses as observations. Supports both static configuration (via attributes) and profile-driven mode (auto-configured from the user's episode profile).

<bio-checkin question-types='["readiness","confidence","worry"]'></bio-checkin>

How It Works

When <bio-checkin> receives context from a parent <bio-provider>:

  1. Resolves configuration — in profile-driven mode, reads question types, schedule, and questionnaire ID from the SDK config; in static mode, parses the question-types attribute
  2. Fetches prior scores — calls GET /api/v1/observations/latest for each biosignal to show the user's last response
  3. Presents questions one at a time — renders a scale (1–5 or 1–10 depending on question type) with step counter
  4. Submits all answers — sends a single POST /api/v1/episodes/:id/questionnaire-response containing all items
  5. Shows results with trends — the server compares each answer to the most recent prior observation and returns a trend (increasing, decreasing, or stable)
  6. Supports updates — an "Update" button lets the user re-submit, and the next trend comparison will use the previous submission as the baseline

Modes

Static Mode

Pass question types directly as an attribute. You control which questions appear:

<bio-checkin
  question-types='["readiness","confidence"]'
  episode-id="ep_abc123">
</bio-checkin>

Profile-Driven Mode

Omit question-types and let the widget auto-configure from the user's episode profile. The profile's spec.sdk.checkin section defines available check-in contexts (e.g., weekly, daily), each with its own question types, schedule, and questionnaire ID.

<bio-checkin context_type="weekly"></bio-checkin>

In profile-driven mode, the widget also reads the check-in status from the SDK config. If the check-in is already completed for the current period, it renders a summary view instead of the questionnaire form.

Attributes

AttributeTypeRequiredDescription
question-typesstringNoJSON array of question type strings (e.g., '["sleep","mood","energy"]'). Omit for profile-driven mode.
episode-idstringNoEpisode ID for submission. Falls back to the episode resolved by <bio-provider>.
questionnaire-idstringNoQuestionnaire identifier. Defaults to "default". Overridden by profile config in profile-driven mode.
context_typestringNoCheck-in context key (e.g., "weekly", "daily"). In profile-driven mode, selects which check-in config to use.

Events

EventDetailDescription
anybio:checkin:submit{ eventId, questionnaireId, observations, episodeId, context }Fired after successful submission. observations is an array of created observation objects including value_quantity, trend, and prior_value.
anybio:checkin:error{ error: string }Fired if submission fails.
anybio:checkin:dismiss{}Fired when the user closes the check-in overlay without completing.
bio-checkin-complete(same as anybio:checkin:submit)Backward-compatible alias.
bio-checkin-error(same as anybio:checkin:error)Backward-compatible alias.
bio-checkin-dismiss(same as anybio:checkin:dismiss)Backward-compatible alias.

Trend Indicators

After submission, each result row can display a trend arrow comparing the current score to the most recent prior observation for that biosignal:

TrendSymbolColor Variable
increasing--bio-trend-improving (green)
decreasing--bio-trend-declining (red)
stable=--bio-trend-stable (gray)
no prior data(hidden)

Trends are computed server-side in the questionnaire-response handler. When no prior observation exists, the trend field is null and no indicator is shown.

CSS Classes

The widget renders with semantic CSS classes for styling. No Shadow DOM — standard CSS selectors work.

ClassElement
.bio-checkin-overlayFull-screen backdrop (static mode)
.bio-checkin-modalModal card
.bio-checkin-headerStep counter + close button row
.bio-checkin-step"1 of 3" step text
.bio-checkin-closeClose (×) button
.bio-checkin-questionQuestion heading
.bio-checkin-prior"Last time: 7/10" prior score
.bio-checkin-scaleScale button container
.bio-checkin-scale-btnIndividual scale button (1–10)
.bio-checkin-labelsLow/High labels
.bio-checkin-summaryCompleted summary card
.bio-checkin-resultsResults list
.bio-checkin-result-itemIndividual result row
.bio-checkin-scoreScore value
.bio-checkin-trendTrend indicator (↑/↓/=)
.bio-checkin-submitted-atTimestamp
.bio-checkin-update-btn"Update" button
.bio-checkin-done-btn"Done" button (static mode)

CSS Custom Properties

PropertyDefaultDescription
--bio-primary#5a8a6aScore and heading accent color
--bio-surface#ffffffCard/modal background
--bio-surface-muted#f8fafcResult row background
--bio-border#e2e8f0Scale button border
--bio-radius8pxBorder radius for result items
--bio-radius-lg12pxBorder radius for cards
--bio-shadow-mdSummary card shadow
--bio-shadow-lgModal shadow
--bio-trend-improving#22c55eIncreasing trend color
--bio-trend-stable#64748bStable trend color
--bio-trend-declining#ef4444Decreasing trend color

Code Examples

Profile-Driven Weekly Check-in

<bio-provider
  api-key="org_your_key"
  project-key="proj_your_key"
  xuser-id="user-123">

  <bio-checkin context_type="weekly"></bio-checkin>

</bio-provider>

The widget reads the weekly entry from the profile's spec.sdk.checkin map. If the user has already completed the weekly check-in, it shows the summary with scores and trends. Otherwise it opens the questionnaire.

With Event Handling

<bio-checkin id="checkin" context_type="weekly"></bio-checkin>

<script>
  document.addEventListener('anybio:checkin:submit', (e) => {
    const { observations, episodeId } = e.detail;
    observations.forEach(obs => {
      console.log(`${obs.biosignal}: ${obs.value_quantity} (${obs.trend})`);
    });
  });

  document.addEventListener('anybio:checkin:dismiss', () => {
    console.log('Check-in dismissed');
  });
</script>

Custom Styling

/* Match your app's design system */
bio-checkin {
  --bio-primary: #1a73e8;
  --bio-radius-lg: 16px;
  --bio-trend-improving: #34a853;
  --bio-trend-declining: #ea4335;
}

/* Style the scale buttons */
.bio-checkin-scale-btn {
  width: 48px;
  height: 48px;
}

/* Customize the summary card */
.bio-checkin-summary {
  border: 1px solid var(--bio-border);
}

Static Mode with All Options

<bio-checkin
  question-types='["readiness","confidence","worry","energy","pain"]'
  episode-id="ep_abc123"
  questionnaire-id="pre_op_weekly">
</bio-checkin>

Roadmap

  • Submission cooldown — Wire up the backend policy cooldown system to enforce frequency limits (e.g., one weekly check-in per 7-day window). The infrastructure exists in the policy engine; it needs to be connected to the questionnaire-response endpoint.

On this page