Notionに溜まった「読んだだけのメモ」を1件ずつ開き、観点となるTagを選び、 その配下の知識ページ(ABC Note)へ自分の言葉のコメントごと転記して、受信箱を空にするアプリ。 データを自前で持たず、Notionを唯一の正本として読み書きする。
抽象度 Lv.4(技術用語+システム上のやりとりまで/製品名・ライブラリ名は書かない)
枠が太く、タイトルに下線のある箱は押せます。
そのブロックの中が何工程に分かれ、誰と何をやりとりしているかの詳しい解説へ進みます。
13ブロックすべてに詳細ページがあります(目次はこちら)。
いちばん下の12番・13番だけは、流れの順番ではありません。
12番は1番より前にある土台(画面がどこで動いて、どう出てくるか)、
13番は3番と8番の間で動いている編集欄です。
先に1〜11を読んでからのほうが「なぜこうなっているか」が分かるので、あとに置いています。
502 を返す。ただし照合に失敗しても書き込みは取り消されない――
「保存できたつもりで実は違った」を防ぐための仕掛けであって、元に戻す仕掛けではない。すべて /api/ の下にあり、すべて 1番の門を通る。画面のHTMLはサーバーで組み立てるが、
中身のデータはこの12本を通してブラウザが取りに行く。
| メソッドとパス | 受け取る形式 | 返す形式 | 主なステータスコード | 担当 |
|---|---|---|---|---|
GET /api/bootstrap | クエリ文字列 ?noteId=(任意) | application/json | 200 / 400 / 401 / 404 / 429 | 2番 |
GET /api/notes/{id} | ― | application/json | 200 / 400 / 401 / 404 | 3番 |
DELETE /api/notes/{id} | ― | application/json | 200 / 400 / 401 / 409 / 502 | 9番 |
POST /api/source-preview | application/json | application/json | 200 / 400 / 401 | 4番 |
POST /api/tags | application/json | application/json | 200 / 400 / 401 / 502 | 5番 |
POST /api/candidate-content | application/json | application/json | 200 / 400 / 401 / 429 | 6番 |
POST /api/uploads | multipart/form-data | application/json | 200 / 400 / 401 / 502 | 7番 |
POST /api/process | application/json | application/json | 200 / 400 / 401 / 409 / 502 | 8番 |
GET /api/map | ― | application/json | 200 / 401 / 404 / 429 | 10番 |
POST /api/map/sub-buried | application/json | application/json | 200 / 400 / 401 | 10番 |
GET /api/lab/recompose | ― | application/json | 200 / 401 / 409 | 11番 |
POST /api/lab/recompose | application/json | application/json | 200 / 400 / 401 / 409 / 502 | 11番 |
コードの意味の使い分け。
400=送られてきた中身が形として間違っている。
401=あなたが誰か分からない(サインインしていない)。
404=Notion側で対象が見つからない、または連携に共有されていない。
409=形は正しいが、いまのNotionの状態と噛み合わない(すでに処理済み、開いてから変わった、など)。
429=Notionへの要求が多すぎる。
502=書いたあとの照合が合わなかった。
503=Notionの接続情報(トークン)が設定されていない。
特徴的なのは、Notionが返したコードがそのまま利用者側の応答コードになること。 Notionが 429 を返せばアプリも 429 を返し、404 を返せばアプリも 404 を返す。 「Notionの状態をそのまま伝える」という方針が、コードの選び方にも出ている。
oai-authenticated-user-id というヘッダを差し込む。
アプリはそのヘッダが存在するかどうかだけを見る。値の中身は照合も記録もしない。401 と日本語のメッセージを返す。Authorization: Bearer … で毎回送り、
あわせて Notion-Version: 2026-03-11 というAPIの版を指定する。
トークンが空なら、Notionへ行く前に 503 で止まる。| 相手 | 誰が呼ぶか | 送るもの | 受け取るもの | 歯止め |
|---|---|---|---|---|
| Notion API | サーバー | application/json(画像だけ multipart/form-data) |
application/json |
429 のときは Retry-After を1〜5秒に丸めて最大2回まで自動で待って再送 |
| 原典の記事サイト | サーバー(4番だけ) | GETのみ。名乗り用の User-Agent を付ける |
text/html など |
8秒で打ち切り/1.5MBで打ち切り/転送は手動で最大4回・毎回宛先を再検査 |
| X(旧Twitter)の埋め込み配信 | ブラウザ(サーバーは介さない) | スクリプトの読み込み要求 | 投稿の表示部品 | 追跡拒否の指定を付ける。読めなければ原典リンクだけを出す |
409 で止まって人に直させる。| 何を | どこで | 有効期間 | 何が変わると捨てるか |
|---|---|---|---|
| 受信箱の一式(2番) | サーバーのメモリ | 30秒 | 保存・削除・Tag作成のたびに即時無効化 |
| 全体マップ(10番) | サーバーのメモリ | 5分 | 同上 |
| ABC候補の下読み(6番) | サーバーのメモリ | 6時間・最大500件 | そのページの最終更新時刻が変わったら |
| サブ埋没の判定(10番) | サーバーのメモリ | 30分 | 最終更新時刻+関連の並びが変わったら |
| 原典プレビュー(4番) | サーバーのメモリ | 15分 | 時間切れのみ |
| ABC候補の応答 | ブラウザ | private, max-age=300 | ― |
| 原典プレビューの応答 | ブラウザ | private, max-age=600 | ― |
| 受信箱・本文・マップの応答 | ブラウザ | no-store(保存させない) | ― |
キャッシュはすべてサーバーのメモリの中に置かれている。ディスクにも外部にも書かない。 置かれている実行環境は要求ごとに切り替わりうるので、 「30秒キャッシュが効く」のは運が良ければ、という程度に読むのが正しい。 正しさはキャッシュに依存せず、書き込み前の再取得と書き込み後の照合で担保している。
409 で断る。502 で失敗したあと、Notion側に半分書かれた状態が残る。それを誰がいつ直すのか(自動で直す仕掛けは見つからなかった)※ この図は、2026年8月14日時点の zettelkasten-inbox のプログラムを読んで作成しました。過去の設計資料は参照せず、いま動いているコードだけを根拠にしています。
※ 番号は処理の流れに沿って 1 から新しく振っています。同じアプリの別の解説資料とは番号が対応しません。
※ 抽象度は Lv.4 で統一しています。通信の方式・データの形式・認証のしくみ・ステータスコードまでは書き、製品名やライブラリ名、関数名やファイルの場所までは踏み込みません(そこは Lv.5)。