共有とディスカッション
レポート は 2 つの方法で公開できます。公開共有(public share) は、URL (と任意のパスコード)を知っていれば誰でも開ける capability リンクを発行します。レポートの不変な 1 バージョンが、Spantail アカウント不要で公開ビューアから配信されます。ディスカッション(discussion) は送信されたコンテンツバージョンごとに付随し、その参加者(レポート所有者とそのバージョンの Send-to 受信者)が本文にリアクションし、スレッド形式のコメントを残せます。
共有はレポートの不変なコンテンツバージョン 1 件を参照します — 所有者がレポート画面から発行すれば現在の バージョン、受信者が受信メッセージから発行すれば配信されたバージョンです。 バージョンは変更されず個別に削除もされないため、後でレポートを編集しても公開ページは変わりません。 プレーンテキストのトークンが capability そのものなので、URL は秘密として扱ってください。
すべての共有は発行した本人が管理します。リンクの一覧・失効ができるのは発行者だけで、所有者と受信者の 一覧が混ざることはありません。
共有オブジェクト
Section titled “共有オブジェクト”| フィールド | 型 | 説明 |
|---|---|---|
id |
string | 一意の識別子。 |
reportContentId |
string | このリンクが配信する不変なレポートバージョン。 |
token |
string | capability トークン(22 文字の base64url 文字列)。公開 URL は /share/<token>。 |
hasPasscode |
boolean | 閲覧にパスコードが必要かどうか。パスコード自体はサーバーから出ません。 |
expiresAt |
string | null | ISO 8601 の有効期限。無期限なら null。 |
revokedAt |
string | null | ISO 8601 の失効時刻。有効なら null。 |
viewCount |
integer | ページが閲覧された回数。 |
lastViewedAt |
string | null | 最後に閲覧された ISO 8601 時刻、または null。 |
createdAt |
string | ISO 8601 の作成時刻。 |
レポートの共有一覧
Section titled “レポートの共有一覧”GET /api/v1/reports/:id/shares scope: read
レポートの所有者が発行した共有(プレーンテキストのトークンを含む)を返します。配信の受信者が発行した
リンクは受信トレイ側のビューに属し、ここには現れません。レポートの読み取りアクセスに従います。
所有者(現在のワークスペースメンバーシップで再チェック)、インスタンス管理者、または単一ワークスペース
レポートのワークスペース管理者・オーナーです。それ以外は 404 を返します。
POST /api/v1/reports/:id/shares scope: write
所有者のみ(現在のワークスペースメンバーシップで再チェック)。レポートの現在の不変バージョンへの リンクを発行します。両フィールドとも任意で、空ボディはパスコードなし・無期限のリンクを発行します。
リクエストボディ
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
passcode |
string | いいえ | 閲覧に必要なパスコード(4〜128 文字)。ハッシュ化して保存(PBKDF2)。 |
expiresInDays |
integer | いいえ | 失効までの日数(1〜365)。省略すると無期限。 |
201 Created を返します。
受信メッセージの共有
Section titled “受信メッセージの共有”POST /api/v1/inbox/:id/shares scope: write
GET /api/v1/inbox/:id/shares scope: read
Send-to の受信者は、受信トレイのメッセージにも同じ公開リンクを発行できます。
リンクが配信するのは配信されたバージョンそのものです。受信者のみが使え、送信者を含む他のユーザーには
404 を返します。受信コピーは受信者のものなので(既にダウンロードもできます)、発行時にワークスペース
メンバーシップの再チェックはありません — 送信時の受信者検証が配布のゲートです。POST のボディは
共有の作成と同じで、GET はこのメッセージのバージョンに対して呼び出し元が発行した
リンクを一覧します。
POST /api/v1/report-shares/:id/revoke scope: write
発行者のみ — レポート所有者、または受信トレイからリンクを発行した受信者。失効は露出を減らすだけなので、
ワークスペースメンバーシップの再チェックは省略されます。冪等で、再失効しても最初の revokedAt を保持
します。失効したリンクはコンテンツの配信を直ちに停止します。更新後の共有オブジェクトを返します。
公開ビューア
Section titled “公開ビューア”公開ビューアは共有されたバージョンを /share/:token で HTML として配信します(/api/v1 プレフィックス
なし・認証なし)。不正・不明・失効・期限切れのトークンはすべて同じ HTML の 404 を返すため、リンクが過去に存在した
ことは決して明かされません。ページは noindex・no-store・厳格な Content-Security-Policy で配信されます。
共有レポートの閲覧
Section titled “共有レポートの閲覧”GET /share/:token public
レポートページを HTML で返します。共有にパスコードがある場合は、代わりにパスコード入力ページを返します。
下の POST フォームでパスコードを送信してください。
パスコードの送信
Section titled “パスコードの送信”POST /share/:token public
フォームエンコードの passcode フィールドを受け付けます。正しいパスコードはレポートページを返し、
誤りはパスコードページを 401 で再表示します。パスコードのない共有はページを直接返します。
ディスカッション
Section titled “ディスカッション”ディスカッションはレポート単位ではなく コンテンツバージョン 単位(/report-contents/:id/…)で
管理されます。送信されたバージョンごとに独立したスレッドを持つため、レポートを編集すると新しい
ディスカッションが始まり、受信者は自分が受け取った本文そのものについてだけ議論します。ID は
reportContentId から解決します — レポート(現行バージョン)
または 受信メッセージ(配信されたバージョン)に
載っています。
バージョンのディスカッションは 参加者(レポート所有者とそのバージョンの Send-to 受信者)に限定 されます。参加者でないインスタンス管理者(または単一ワークスペースレポートのワークスペース管理者・ オーナー)は、レポートの読み取りアクセスのもとでスレッドを 読む ことはできますが、書き込みは参加者 専用です。コメントとリアクションは、そのバージョンが共有された後(配信が 1 件以上ある)にのみ書き込め ます。未送信のバージョンは空の読み取り専用スレッドです。
コメントオブジェクト
Section titled “コメントオブジェクト”| フィールド | 型 | 説明 |
|---|---|---|
id |
string | 一意の識別子。 |
reportContentId |
string | このコメントが属するコンテンツバージョン。 |
authorUserId |
string | null | 作成者。アカウント削除後は null(固定の authorName が単独で残る)。 |
authorName |
string | 作成者の表示名。書き込み時に固定。 |
authorImageUrl |
string | null | 作成者のライブアバター URL、または null。 |
body |
string | Markdown のコメント本文。 |
createdAt |
string | ISO 8601 の作成時刻。 |
updatedAt |
string | ISO 8601 の最終更新時刻。 |
editable |
boolean | 呼び出し元が作成者のとき true(編集/削除メニューを駆動)。 |
reactions |
object[] | このコメントへの集計済みリアクション(下記参照)。 |
リアクション集計 は 1 つの絵文字を集約します: { "emoji": "+1", "count": 2, "reactedByMe": true, "userNames": ["Ana", "Bo"] }。リアクション絵文字はグリフではなく安定したコンテンツキーです: +1、-1、
laugh、hooray、confused、heart、rocket、eyes。
ディスカッションの取得
Section titled “ディスカッションの取得”GET /api/v1/report-contents/:id/discussion scope: read
バージョンの本文レベルのリアクションとコメント(各自のリアクション付き)に加え、shared を返します。
一度も送信されていないバージョンでは shared は false(その場合 UI はパネルを隠します)。
コメントの追加
Section titled “コメントの追加”POST /api/v1/report-contents/:id/comments scope: write
参加者のみ。バージョンが共有済みである必要があります。作成したコメントを 201 で返します。
リクエストボディ
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
body |
string | はい | Markdown のコメント(1〜10000 文字)。 |
コメントの編集
Section titled “コメントの編集”PATCH /api/v1/report-contents/:id/comments/:commentId scope: write
作成者のみ。作成と同じ body フィールド。存在しないコメント・誤ったバージョン・非作成者はいずれも 404 を
返し、区別されません。
コメントの削除
Section titled “コメントの削除”DELETE /api/v1/report-contents/:id/comments/:commentId scope: write
作成者のみ。204 No Content を返します。
バージョン本文へのリアクション
Section titled “バージョン本文へのリアクション”PUT /api/v1/report-contents/:id/reactions scope: write
参加者のみ。バージョンが共有済みである必要があります。指定された絵文字での呼び出し元のリアクションを バージョン本文にトグルします(同じ絵文字で再度呼ぶと解除)。本文の更新後のリアクション集計を返します。
リクエストボディ
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
emoji |
string | はい | リアクションキーのいずれか(+1、-1、laugh、hooray、confused、heart、rocket、eyes)。 |
コメントへのリアクション
Section titled “コメントへのリアクション”PUT /api/v1/report-contents/:id/comments/:commentId/reactions scope: write
参加者のみ。単一コメント(そのバージョンに属することを検証)への呼び出し元のリアクションをトグル します。そのコメントの更新後のリアクション集計を返します。