コンテンツへスキップ

経験サンプリング、追跡調査ウェーブ、デルファイ・ラウンド

登録の数時間後や数週間後にアンケートセッションを開き、メール、Twilio の SMS、Prolific のメッセージで参加者にリマインドし、回答率と応答遅延をエクスポートします。

v2.13.0 で新登場

schedule: ブロックを使うと、Potato は参加者の最初の訪問から一定時間が過ぎた後に短いアンケートセッションを開きます。notifications: ブロックを使うと、各セッションが開く際にメール、SMS、Prolific のメッセージで通知を送れます。調査研究者は縦断パネルの追跡調査ウェーブに、心理学者や保健分野の研究者は日記調査や気分調査の経験サンプリングに、専門家パネルは基準やガイドラインの合意形成のためのデルファイ・ラウンドに、この機能を使います。Potato はセッションごとに、回答、プロンプトを送信した時刻、参加者が初めてフォームに触れた時刻、そして回答済み、期限切れ、未回答のどれであったかを記録します。

経験サンプリング法(ESM)は、各プロンプトの瞬間について、同じ短い質問を一日に数回、参加者に尋ねる手法です。保健分野の研究者は同じ設計を生態学的瞬間評価(EMA)と呼びます。デルファイ法では、専門家パネルが同じ項目を複数のラウンドにわたって評価し、再評価の前に前回ラウンドのパネルの匿名の回答を見ます。

  • タイムゾーン。 各参加者は登録時にタイムゾーンを選びます。登録ページにはブラウザーのタイムゾーンが入力済みになります。"09:00" のような時刻は、各現地日付における参加者のタイムゾーンで解釈されます。
  • チャネル。 メッセージは任意の SMTP サーバー経由のメール、Twilio 経由の SMS、または参加者の Prolific の受信箱に届きます。認証情報は環境変数からのみ読み込まれます。
  • 連絡先。 Potato は、同意の質問に「はい」と答えた後にのみメールアドレスまたは電話番号を尋ね、アドレスを出力ディレクトリの外に置き、どのエクスポートにも含めません。

登録とセッション計画

各参加者は、次の手順を一度だけ通ります。

  1. 参加者は、同意、説明、アノテーション、アンケートという通常のフローを完了します。
  2. フローの終わりに、登録ページがタイムゾーンを尋ね、同意の質問に「はい」と答えた場合にのみメールアドレスまたは携帯電話番号を尋ねます。スクリーニングで除外された参加者、トレーニングに不合格だった参加者、注意チェックでブロックされた参加者は登録されません。
  3. Potato はその時点で、参加者のすべてのセッションとすべてのリマインダーを計算し、計画を保存します。
  4. バックグラウンドのループが、各メッセージを予定時刻に送信します。メッセージには、参加者をサインインさせてセッションを開く再開リンクが付きます。
  5. 調査リンクから戻ってきた参加者は、開いているセッションに進むか、次のセッションが開く時刻を参加者自身のタイムゾーンで示すステータスページに進みます。

計画とタイムゾーンは登録時に固定されます。後から waves を編集しても、変更が反映されるのはその後に登録する参加者の計画だけです。連絡を断った参加者も登録は維持され、メッセージは届きませんが、調査リンクに戻ることで開いているセッションを見つけられます。

設定

以下の設定は、09:00 から 21:00 の間のランダムな時刻に一日五回のプロンプトを出す、七日間の経験サンプリング調査を実行します。通常のフローは同意ページと一つのイントークアイテムで、イントークアイテムを完了すると参加者が登録されます。

yaml
annotation_task_name: "Daily mood study"
task_dir: .
output_annotation_dir: annotation_output
data_files: [data/intake.jsonl]
item_properties: {id_key: id, text_key: text}
user_config:
  allow_all_users: true
 
phases:
  order: [consent, annotation]
  consent:
    type: consent
    file: surveys/consent.json
  annotation:
    type: annotation
 
annotation_schemes:            # the intake questions, answered once
  - annotation_type: likert
    name: usual_mood
    description: "In general, how would you describe your mood?"
    size: 7
    min_label: "Very low"
    max_label: "Very good"
 
schedule:
  timezone: "America/Detroit"  # used when the browser reports no time zone
  seed: "daily-mood-2026"
  experience_sampling:
    title: "How are you right now?"
    days: 7
    start_day: 1               # first prompts on the day after enrollment
    daily_window: "09:00-21:00"
    signal: {per_day: 5, min_gap: 90m}
    expires_after: 30m
    questions:
      - {name: mood, annotation_type: likert, size: 7, required: true,
         description: "How do you feel right now?",
         min_label: "Very bad", max_label: "Very good"}
      - {name: company, annotation_type: radio, required: true,
         description: "Who are you with?",
         labels: ["Alone", "Family", "Friends", "Colleagues", "Strangers"]}
    reminders:
      - at: open
      - after_open: 15m
 
notifications:
  dry_run: true                # pilot: render and log every message, send none
  base_url: "https://mood-study.example.org"
  channels:
    - type: log
    - type: twilio
      account_sid_env: TWILIO_ACCOUNT_SID
      auth_token_env: TWILIO_AUTH_TOKEN
      from_number: "+12025550143"
  contact:
    consent: {question: contact_consent, value: "Yes"}

二つのリマインダーは、プロンプトが開いた時点でプロンプトを送り、その 15 分後に、まだ回答していない参加者へ二通目のメッセージを送ります。dry_run: true の間、Potato はすべての Twilio メッセージを生成して宛先を付け、管理ページに各メッセージを一覧表示しますが、配信は行いません。パイロットが終わったら dry_run: false に設定してください。ランダムなプロンプト時刻は、seed、参加者 ID、日付から抽出されます。各参加者は独立した抽出結果を得て、その抽出結果は後から再計算できます。

surveys/consent.json の同意ページは、notifications.contact.consent が指定する質問を尋ねます。

json
[
  {"name": "study_consent", "annotation_type": "radio",
   "description": "I agree to answer short surveys five times a day for seven days.",
   "labels": ["I agree", "I do not agree"],
   "label_requirement": {"required_label": ["I agree"]}},
  {"name": "contact_consent", "annotation_type": "radio",
   "description": "May we text you when each survey opens? Your number is kept apart from your answers and deleted when the study ends.",
   "labels": ["Yes", "No"],
   "label_requirement": {"required": true}}
]

起動時に Potato は、contact_consent がフェーズページで尋ねられていること、および Yes がその質問の選択肢の一つであることを確認します。YAML 1.1 は裸の Yes を真偽値として読み、同意の値が true または false になると検証に失敗するため、YAML では "Yes" を引用符で囲んでください。value には、連絡を許可する回答のリストを指定することもできます。

経験サンプリングのオプション

experience_sampling のキーデフォルト意味
days必須サンプリング日数。1 から 366
start_day1登録日から数えた最初のサンプリング日。0 は登録日そのもの
daily_window"09:00-21:00"プロンプトが出る現地時間のウィンドウ
signal.per_daysignal を使う場合は必須一日あたりのランダムなプロンプト数。1 から 48
signal.min_gap60m二つのプロンプトの最小間隔。expires_after 以上
interval.everyなしウィンドウの開始時と、開始後に一定間隔ごとのプロンプト
interval.timesなし["10:00", "14:00", "20:00"] のような、固定の現地時刻
expires_after30m各プロンプトが開いている時間。最低 1 分
questions, questions_fileどちらか一つが必須プロンプトの質問(下のセッションの質問のセクションを参照)
reminders[{at: open}]at: open、after_open、before_close。before_open は拒否されます
title"Short survey"プロンプトのページとメッセージに表示されます
introなし質問の上に表示するテキスト

一つの調査では、signal(シグナル随伴型、ランダムな時刻)と interval(間隔随伴型、固定の時刻)のうち、ちょうど一つを使います。interval ブロックは every と times のうちちょうど一つを取ります。期間は 30m、48h、7d、2w のように、または秒数で書きます。

一日のウィンドウに収まらない計画は、検証に失敗します。90 分間隔の五回のプロンプトには、90 分の間隔が四つと、最後のプロンプトが開いている 30 分が必要で、ウィンドウのうち 6 時間 30 分を占めます。同じ間隔の九回のプロンプトには 12 時間 30 分が必要で、12 時間のウィンドウでは検証に失敗します。ウィンドウより長い interval.every や、expires_after より近い固定時刻も、同じように失敗します。

Potato は日ごとに、参加者のタイムゾーンにおけるその現地日付に一日のウィンドウを置きます。そのため、時計が切り替わる日でも、ウィンドウは現地時間の 09:00 から 21:00 までになります。ランダムな時刻は、プロンプト同士が少なくとも min_gap 離れ、最後のプロンプトがウィンドウ内で閉じるすべての配置から、一様に抽出されます。ステータスページには、その日のウィンドウが表示され、次のランダムなプロンプトの時刻は決して表示されません。登録の時点ですでに時刻を過ぎているプロンプトは除外されます。

追跡調査ウェーブ

縦断パネルでは waves を使います。以下の部分的なブロックは、上の設定の schedule を置き換え、一週間後と一か月後の追跡調査を追加します。

yaml
schedule:
  timezone: "America/Detroit"
  waves:
    - name: week1
      title: "One-week follow-up"
      offset: 7d
      at: "09:00"              # local clock time on day 7
      window: 48h
      questions:
        - {name: changed_view, annotation_type: radio, required: true,
           description: "Since last week, has your view changed?",
           labels: ["No", "A little", "A lot"]}
      reminders:
        - before_open: 12h
        - at: open
        - before_close: 12h
      completion_code: "FOLLOWUP-DONE"
    - name: month1
      offset: 30d
      at: "09:00"
      window: 72h
      questions_file: surveys/followup.json

at を指定すると、その間に時計が切り替わっても、各ウェーブは指定した日の現地時間 09:00 に開きます。この場合、offset は日数の整数でなければなりません。at がない場合、offset: 7d は経過時間で七日を意味し、夏時間の切り替えによって現地での開始時刻が一時間ずれます。"09:00" のような時刻は引用符で囲んでください。YAML 1.1 は引用符のない 10:30 を数値の 630 として読み、Potato は 630 を午前 0 時からの分数として読みます。

waves のキーデフォルト意味
name必須エクスポートで使う、英字、数字、_、- の 40 文字以内の短い ID
titlename参加者とメッセージに表示されます
offset0登録後の経過時間
atなし登録から offset 日後の日の現地時刻
window必須ウェーブが開いている時間。最低 1 分
questions, questions_fileどちらか一つが必須ウェーブの質問
reminders[{at: open}]メッセージを送るタイミング
completion_codeなし参加者がウェーブを送信した後に表示されるコード。たとえば二つ目の Prolific 調査で報酬を請求するために使います
introなし質問の上に表示するテキスト

デルファイ・ラウンド

デルファイ調査では delphi を使います。以下の部分的なブロックは、経験サンプリングの設定の schedule を置き換えます。data/criteria.json には {"id", "text"} のアイテムのリストを入れます。

yaml
schedule:
  timezone: "UTC"
  delphi:
    title: "Guideline criteria"
    items_file: data/criteria.json
    scale: {min: 1, max: 9, min_label: "Not important", max_label: "Essential"}
    comments: true
    max_rounds: 3
    round_length: 72h
    gap: 12h
    start: "2026-11-16T09:00:00-05:00"
    min_panel: 3
    stop:
      iqr_at_most: 1
      changed_share_below: 0.15
    reminders:
      - at: open
      - before_close: 24h

ラウンドはパネル全体で共通です。第 1 ラウンドは start の時刻に開きます。start が設定されていない場合は、この設定での最初のサーバー起動時に開き、Potato はその時刻を再起動後も保持します。以降の各ラウンドは、前のラウンドが閉じてから gap 後に開きます。第 2 ラウンドの間に登録したパネリストは第 2 ラウンドに参加し、自分自身の評価がない状態で第 1 ラウンドのフィードバックを見ます。メッセージを停止したパネリストにも、リマインダーなしで各ラウンドが届きます。

第 2 ラウンド以降、各アイテムには前のラウンドについて次の情報が表示されます。

  • 中央値、尺度上に帯で示される評価の中央の半分(Q1 から Q3)、およびパネリスト自身の評価の印。
  • 評価の件数。
  • 他のパネリストのコメント。名前は付かず、パネリストごとに固定された順序で表示されます。パネリスト自身のコメントは繰り返し表示されません。

min_panel 人未満のパネリストしか評価していないアイテムには、要約もコメントも表示されません。この閾値により、小規模なパネルの評価が特定の一人に結び付けられることはありません。現在のラウンドの評価が事前入力されることはありません。

ラウンドがウィンドウの終わりに閉じたとき、または管理者が /admin/schedule でラウンドを早めに閉じたとき、Potato は各アイテムの n、中央値、平均、Q1、Q3、四分位範囲(IQR)を計算します。四分位数は順序統計量の間の線形補間を使います。これは R が type 7 と呼ぶ方法で、NumPy のデフォルトでもあります。第 2 ラウンド以降、Potato は median_change と changed_share も計算します。median_change は中央値の絶対的な変化で、changed_share は両方のラウンドでそのアイテムを評価し、かつ評価を変更したパネリストの割合です。アイテムは、設定された基準を少なくとも一つ満たしたときに、確定とみなされます。

stop のキー種類確定とみなす条件
iqr_at_most合意IQR がその値以下
median_change_at_most安定性、第 2 ラウンドから前のラウンドからの中央値の移動がその値以下
changed_share_below安定性、第 2 ラウンドから評価を変更したパネリストの割合がその値を下回る。0 から 1

調査は、すべてのアイテムが確定した最初のラウンドの後、または max_rounds の後に停止します。stop ブロックがない場合、調査は max_rounds のラウンドをすべて実行します。停止の理由は、パネリストのステータスページと管理ページに表示されます。

delphi のキーデフォルト意味
items, items_fileどちらか一つが必須[{id, text}] をインラインで、または JSON、JSONL、YAML のファイルで指定
scale{min: 1, max: 9}21 点以下の整数の評価尺度。min_label と max_label は任意
commentstrueアイテムごとの任意のコメント(2,000 文字以内)。名前なしでパネルに表示されます
max_rounds3ラウンド数の上限。1 から 10
round_length必須各ラウンドが開いている時間
gap0あるラウンドが閉じてから次が開くまでの時間
start最初のサーバー起動第 1 ラウンドが開く時刻。UTC オフセット付きの ISO 8601 で指定
min_panel3アイテムの要約とコメントを表示するために必要な評価の数
stopなし停止基準
reminders[{at: open}]メッセージを送るタイミング
title"Delphi round"ラウンドのページに表示され、ラウンド番号が続きます
introなしアイテムの上に表示するテキスト

セッションの質問

ウェーブとプロンプトの質問は、アノテーションスキームと同じ形で書きます。questions の下にインラインで書くか、設定ファイルからの相対パスで読み込まれる JSON または YAML の questions_file に書きます。各質問は name、annotation_type、description と、required: true か label_requirement: {required: true} のどちらかを取ります。六つの質問タイプは、次のキーを取ります。

タイプキーとデフォルト
radiolabels(2 つ以上)、horizontal
multiselectlabels(2 つ以上)
likertsize(2 から 11)、min_label、max_label
slidermin_value(0)、max_value(100)、starting_value(min_value)、step(1)、min_label、max_label
numbermin_value、max_value、integer
textmultiline(true)、max_length(1000、最大 4,000)

そのタイプの一覧にないキーは、検証に失敗します。slider のアノテーションスキームとは異なり、セッションの slider は min_label と max_label を取ります。スライダーは、参加者がスライダーを動かした後にのみ回答済みとして数えられ、サーバーは質問の選択肢や範囲の外にある回答を拒否します。Potato はセッションの回答を、user_state.json ではなく、セッションごとに <output_annotation_dir>/scheduling/schedule.sqlite に保存します。上の設定では、一人の参加者が各プロンプトの質問に、プロンプトごとに一回、合計 35 回回答できます。

リマインダー

各ウェーブ、経験サンプリングのブロック、デルファイのブロックは、四つのルールからなる reminders のリストを取ります。

ルールメッセージを送るタイミング
{at: open}ウィンドウが開いたとき
{before_open: 12h}ウィンドウが開く 12 時間前
{after_open: 2h}ウィンドウが開いた 2 時間後。セッションがまだ回答されていない場合
{before_close: 12h}ウィンドウが閉じる 12 時間前。セッションがまだ回答されていない場合

セッションがすでに回答済みまたは終了している場合、Potato はリマインダーを送信しません。また、セッションがすでに開いた後は before_open のリマインダーを送信しません。参加者が登録する前に予定時刻を迎えたリマインダーは送信されません。after_open または before_close のオフセットは、ウィンドウより短くなければなりません。経験サンプリングは before_open を受け付けません。メッセージがランダムなプロンプトを事前に知らせてしまうためです。

通知

以下の部分的なブロックは、上の設定の notifications を置き換え、メールと Prolific の受信箱にメッセージを送り、プロンプト用にカスタムのテキストを使います。

yaml
notifications:
  base_url: "https://mood-study.example.org"
  channels:
    - type: log
    - type: smtp
      host: smtp.example.org
      port: 587
      security: starttls        # starttls, ssl, or none
      username_env: POTATO_SMTP_USER
      password_env: POTATO_SMTP_PASSWORD
      from: "Mood study <mood-study@example.org>"
    - type: prolific
      token_env: PROLIFIC_API_TOKEN
  templates:
    prompt:
      subject: "{study}: a short survey is open"
      body: "Please answer within {time_left}: {link}\n\nStop messages: {stop_link}"
  contact:
    consent: {question: contact_consent, value: "Yes"}
    delete_after_study: true

各チャネルタイプは一度だけ指定できます。

チャネル配信先キーとデフォルト
logサーバーログと管理ページ。全文とリンクを含みます。参加者には何も届きませんなし
smtp登録時に入力されたメールアドレスhost(必須)、from(必須)、security(starttls)、port(587、ssl の場合は 465)、username_env と password_env(両方か、どちらもなし)、timeout(20 秒)
twilio登録時に入力された携帯電話番号。SMS で配信account_sid_env(TWILIO_ACCOUNT_SID)、auth_token_env(TWILIO_AUTH_TOKEN)、from_number(E.164 形式の番号)と messaging_service_sid_env のうちちょうど一つ、timeout(20)
prolific参加者の Prolific の受信箱。Prolific の参加者 ID で宛先を指定token_env(PROLIFIC_API_TOKEN)、study_id(未設定の場合は参加者の STUDY_ID)、timeout(30)

Prolific チャネルが届くのは、Prolific から来た参加者のみです。Potato は、*_env キーが指す各変数を、メッセージの送信時に読み込みます。YAML に password、token、account_sid のようなキーで認証情報が書かれている場合、Potato は起動時に停止します。変数が見つからない場合は起動時にログに記録され、そのチャネルの各メッセージは変数名とともに失敗します。Potato を起動する前に、サーバーの環境に変数を設定してください。

bash
export POTATO_SMTP_USER="mood-study@example.org"
export POTATO_SMTP_PASSWORD="<your SMTP password>"
export PROLIFIC_API_TOKEN="<your Prolific API token>"
notifications のキーデフォルト意味
dry_runfalseすべてのチャネルですべてのメッセージを生成して宛先を付け、配信せずに各メッセージを dry_run として記録します
base_urlhttp://localhost:<port>リンクに使う公開アドレス。log 以外のチャネルでは、dry_run がオンでない限り必須
channelsなし上記のチャネル
contact.consentチャネルを使う場合は必須{question, value}。フェーズページ上の同意の質問と、連絡を許可する回答
contact.delete_after_studytrue参加者に残りのセッションがなくなった時点で、その参加者の連絡先を削除します
templates組み込み種類ごとのメッセージテキスト

テンプレートの種類は、before_open、open、reminder(after_open と before_close 用)、prompt(経験サンプリングのプロンプトの最初のメッセージ)、delphi_round です。各種類は subject と body を取ります。プレースホルダーは {study}、{session}、{opens}、{closes}、{time_left}、{link}、{stop_link} です。Potato は {opens} と {closes} を参加者のタイムゾーンで表示し、テンプレートが未知のプレースホルダーを使っている場合は起動時に停止します。SMS は本文のみを使い、Twilio の上限である 1,600 文字までで、Prolific のメッセージは件名と本文を連結します。

Potato は、送信の前にデータベース内で各メッセージを確保します。そのため、再起動後や二つ目のサーバープロセスからでも、同じメッセージが二度送られることはありません。送信の途中で中断されたメッセージは失敗としてマークされ、再送されません。一時的なエラーの後は、セッションがまだ開いている間、Potato は 5 分後と 10 分後に再試行し、合計で最大三回まで試みます。一時的なエラーとは、SMTP の接続エラーと、Twilio または Prolific の 429 または 5xx の応答です。それ以外のエラーはただちに失敗します。

スケジュール全体の設定

schedule のキーデフォルト意味
timezoneUTCブラウザーがタイムゾーンを報告しない場合に、登録ページで事前に選択される IANA タイムゾーン
seed空ランダムなプロンプト時刻とデルファイのコメントの順序に混ぜ込まれるテキスト
poll_seconds30バックグラウンドのループが実行される間隔。1 から 3,600 秒
schedulertrueサーバーとともにバックグラウンドのループを実行します
waves, experience_sampling, delphiなし少なくとも一つが必須

バックグラウンドのループは、予定のメッセージを送信し、デルファイのラウンドを開閉し、終了した参加者の連絡先を削除します。scheduler: false の場合、管理者が /admin/schedule で Send due messages now を押すか、/admin/api/schedule/tick に POST するまで、何も送信されません。schedule ブロックのない notifications ブロックは、検証に失敗します。

再開リンクと連絡先

再開リンク(/s/<token>)は、参加者をサインインさせ、一つのセッションを開き、セッションが閉じると失効します。リンクは POTATO_SCHEDULE_LINK_KEY のもとで HMAC-SHA256 により署名されます。この変数が設定されていない場合は、<task_dir>/.potato/scheduling/link.key に一度だけ生成されるランダムなキーで署名されます。サーバーが新しいディスクで再起動する可能性がある場合は、この変数を設定してください。参加者がメッセージを停止すると、Potato はその参加者に以前送信したすべてのリンクを無効にします。

メールアドレスと電話番号は、アノテーションの出力ディレクトリの外にある <task_dir>/.potato/scheduling/contacts.sqlite に、ファイルモード 0600 で保存されます。どのエクスポーター、データアーカイブ、デプロイバンドルも連絡先ストアを読まず、通知ログに記録されるのはチャネルのみで、アドレスは記録されません。再起動のたびにディスクを消去するホストではアドレスが失われ、そのホストの参加者にはそれ以降のメッセージが届きません。

参加者は、ステータスページから、またはすべてのメッセージに含まれる停止リンクから、メッセージを停止できます。停止リンクは確認ページを開き、連絡先を削除するのはそのページのボタンだけです。したがって、メールスキャナーがリンクを開いても、誰かの配信が停止されることはありません。delete_after_study: true の場合、参加者に開いているセッションも今後のセッションもなくなった時点で連絡先が削除され、デルファイ調査ではパネルが終了するまで連絡先が保持されます。

未回答と期限切れのセッション

セッションは、そのセッションのウィンドウの終わりに閉じ、サーバーは閉じた後に送信された回答を拒否します。Potato は、閉じたセッションを三つの状態のいずれかで記録します。

  • answered は、参加者が終了前にセッションを送信したことを意味します。
  • expired は、参加者がセッションを開いたか回答を始めたものの、終了前に送信しなかったことを意味します。
  • missed は、セッションが開いている間に参加者が一度もセッションを開かなかったことを意味します。

Potato は閉じたセッションを再スケジュールせず、そのセッションの保留中のリマインダーは送信されません。古いリンクを開いた参加者には、セッションがいつ閉じたかと、次のセッションがいつ開くかが表示されます。ただし、次のセッションがランダムなプロンプトの場合は表示されません。回答率は、回答済みセッション数を閉じたセッション数で割った値で、参加者ごと、およびセッションの種類ごとに算出されます。

管理ページ

/admin/schedule には、管理 API キーまたは RBAC の管理者ロールが必要です。このページには、各参加者のタイムゾーン、同意、回答率、応答遅延の中央値、次のセッションが表示され、すべてのメッセージがステータス別に一覧されます。log と dry_run のメッセージには全文が付きます。デルファイのラウンドは、アイテムの統計とともに表示されます。ページ上のボタンは、以下の POST エンドポイントに対応します。

エンドポイントメソッドアクション
/admin/api/scheduleGETアドレスを含まない、ページのデータを JSON で返します
/admin/api/schedule/tickPOST予定のメッセージをただちに送信します
/admin/api/schedule/delphi/close_roundPOST開いているデルファイのラウンドを閉じます
/admin/api/schedule/contact/<participant>/deletePOST一人の参加者の連絡先を削除します

エクスポート

セッションの回答はアイテムのアノテーションではないため、メインのエクスポートにはセッションの回答は含まれません。代わりに schedule エクスポートがサイドカーテーブルを書き出し、すべてのテーブルには、メインのエクスポートの user_id と同じ ID を持つ participant 列があります。

bash
python -m potato.export --config config.yaml --format schedule --output out/
ファイル行
schedule_sessions.csv参加者とセッションごとに一行。通常のフロー用に、参加者ごとに enrolment の行が一つ加わります
schedule_compliance.csv参加者とセッションの種類ごと。sessions、closed、answered、expired、missed、compliance、median_latency_seconds を含みます
schedule_notifications.csv予定されたすべてのメッセージ。session_id、rule、template、channel、due_at_utc、status、attempts、sent_at_utc、detail を含みます。アドレスもメッセージ本文も含みません
delphi_ratings.csvデルファイのみ。participant、round、item、rating、comment を含みます
delphi_rounds.csvデルファイのみ。ラウンドとアイテムごと。n、median、q1、q3、iqr、mean、median_change、changed_share、settled、opens_at_utc、closed_at_utc、round_status、stop_reason を含みます

デルファイの評価は delphi_ratings.csv に書き込まれ、ラウンドのセッションはステータスと応答遅延とともに schedule_sessions.csv に現れます。schedule_sessions.csv の列は次のとおりです。

列意味
kindwave、prompt、round、または enrolment
session_id, wave, day, prompt, round, titleその行がどのセッションかを示します。day は 1 から始まるサンプリング日、prompt はその日のプロンプトの番号です
timezone参加者のタイムゾーン
opens_at_utc, closes_at_utc, opens_at_local, closes_at_localUTC と現地時間でのウィンドウ
statusanswered、expired、missed、open、started、または upcoming(登録の行では enrolled)
prompt_at_utc最初のメッセージが送信された時刻。メッセージが送られていない場合はウィンドウの開始時刻
opened_at_utc, first_answer_at_utc, submitted_at_utc参加者がページを開いた時刻、最初にフォームに触れた時刻、送信した時刻
latency_secondsprompt_at_utc から最初の回答まで
response_seconds最初の回答から送信まで
reminder_channels参加者がメッセージを受け取るチャネル。登録の行に入ります
answer.<name>質問ごとに一列。multiselect の回答は ; で連結されます

例

bash
python potato/flask_server.py start examples/advanced/experience-sampling/config.yaml -p 8000

この例は、log チャネルとドライランの Twilio チャネルを使って、上のサンプリング計画を実行します。/admin/schedule の管理ページには、各プロンプトの再開リンクが一覧表示されます。examples/advanced/two-wave-panel/ と examples/advanced/delphi-study/ のフォルダーには、一週間の追跡調査パネルと、三ラウンドのデルファイ調査が入っています。

関連資料

実装の詳細については、ソースドキュメントを参照してください。