{% extends "base.html" %} {% block title %}Funnel — CareAgents{% endblock %} {% block bodyclass %}page-home{% endblock %} {# The owner's page (careagents/funnel.py, CARE_OWNER_EMAILS). Counts, account ids, and the Testers table, which shows each tester's email (owner decision 2026-10-16: this page and its CSV only, never the digest or a log). No message, nothing about a record. #} {% block content %}

Funnel

Counts per UTC day. Today is {{ today.day }}.

Back to your hub
{# Morning: the loop in order, then who needs a nudge today. The owner's own account is not counted. The nudges are fixed words chosen by fixed rules (signins.needs_you); nothing here comes from a chat. #}

Morning

{% for step in morning_loop.chain %}{{ step.count }} {{ step.label }}{% if not loop.last %}{% endif %}{% endfor %}

{% for s in morning_loop.side %}{{ s.count }} {{ s.label }}{% if not loop.last %}{% endif %}{% endfor %}

Testers, not counting you. Along the arrows, each number counts only those who also reached the steps before it. Everyone starts on made-up records, so asking and acting do not need their own records. Came back: active again on a later day than the one they joined.

Needs you today

{% if needs_you %} {% else %}

Nobody is stuck today.

{% endif %}

Testers

Download CSV
{% if testers %}

Newest first{% if testers|length >= testers_cap %}, the latest {{ testers_cap }}{% endif %}. Highlighted: joined but never asked a question, or no chat turn or approval for 3 days or more. Joined is the first sign-in. Times are UTC. Milestones: how many of the {{ milestones | length }} steps the tester has reached: {{ milestones | map("replace", "_", " ") | join(", ") }}.

{% for t in testers %} {# Joined is the first sign-in: an account is made only at one. #} {% endfor %}
EmailStuck atLast active JoinedLast sign-inSign-ins, 7 days Milestones
{{ t.email }}{% if t.is_owner %} you{% endif %} {{ (t.furthest or "-") | replace("_", " ") }}{% if t.idle_days is not none %}
{{ t.idle_days }}d since {% if t.last_active %}active{% else %}joined{% endif %}{% endif %} {% if t.stuck %}
{{ t.stuck_reason }}{% endif %}
{{ t.last_active or "never" }}{{ t.joined }}
{{ t.joined_label }}{% if t.ref and t.ref != t.inviter %}
ref: {{ t.ref }}{% endif %}
{{ t.last_sign_in or "-" }}{% if t.last_method_label %}
{{ t.last_method_label }}{% endif %}
{{ t.sign_ins_7d }} {% if t.milestones %}
{{ t.milestones | length }} of {{ milestones | length }}{{ t.milestones | map("replace", "_", " ") | join(", ") }}
{% else %}0 of {{ milestones | length }}{% endif %}
{% else %}

No accounts yet.

{% endif %}

Accounts reaching each step

{% for d in report.days[1:] %}{% endfor %} {% for m in milestones %} {# "confirmed" alone read as an unverified email (patient walk). #} {% for d in report.days[1:] %}{% endfor %} {% endfor %} {% for d in report.days[1:] %}{% endfor %}
StepToday7 days{{ d.day[5:] }}
{% if m == "confirmed" %}confirmed a beta request{% else %}{{ m | replace("_", " ") }}{% endif %} {{ today[m] }} {{ report.window[m] }}{{ d[m] }}
joined via invite {{ today.via_invite }} {{ report.window.via_invite }}{{ d.via_invite }}

Beta requests waiting to be confirmed: {{ report.requests_waiting }}

Conversion between steps (all time)

{% for c in report.conversion %} {% endfor %}
FromToReachedRate
{{ c["from"] | replace("_", " ") }} {{ c["to"] | replace("_", " ") }} {{ c.to_n }} of {{ c.from_n }} {% if c.percent is none %}-{% else %}{{ c.percent }}%{% endif %}

Issues

{% for k in issue_kinds %} {% endfor %}
KindToday7 days
{{ k | replace("_", " ") }} {{ today[k] }} {{ report.window[k] }}
{% for k in chat_error_causes %} {% endfor %}
Chat error causeToday7 days
{{ k | replace("_", " ") }} {{ today[k] }} {{ report.window[k] }}

Invites per inviter

{% if report.per_inviter %}
{% for r in report.per_inviter %} {% endfor %}
Inviter accountJoined
{{ r.inviter_id }}{{ r.joined }}
{% else %}

Nobody has joined through an invite link yet.

{% endif %}
{% endblock %}