← ガイダンス一覧へ戻る

Zettelkasten Inbox / アーキテクチャ

Notionに溜まった「読んだだけのメモ」を1件ずつ開き、観点となるTagを選び、 その配下の知識ページ(ABC Note)へ自分の言葉のコメントごと転記して、受信箱を空にするアプリ。 データを自前で持たず、Notionを唯一の正本として読み書きする。

抽象度 Lv.4(技術用語+システム上のやりとりまで/製品名・ライブラリ名は書かない)
入口・読取・選択 書き込み系 データの正本・外部 左の破線=Notionとの往復/右の破線=外部サイトの読み取り

枠が太く、タイトルに下線のある箱は押せます。 そのブロックの中が何工程に分かれ、誰と何をやりとりしているかの詳しい解説へ進みます。 13ブロックすべてに詳細ページがあります(目次はこちら)。

いちばん下の12番・13番だけは、流れの順番ではありません。 12番は1番より前にある土台(画面がどこで動いて、どう出てくるか)、 13番は3番と8番の間で動いている編集欄です。 先に1〜11を読んでからのほうが「なぜこうなっているか」が分かるので、あとに置いています。

利用者(ブラウザ)
受信箱の画面/全体マップの画面/再構成ラボの画面。3画面ともブラウザ側で組み立てる
1 アクセス確認と共通の応答 ›
12あるAPIすべての先頭に立つ門。サインイン済みかを見て、通らなければ本文を読む前に 401 を返す
読む ― 何が溜まっているか、この1件は何か
2 受信箱の初期読込 ›
Notionの3つのデータベース(Literature/Tag/ABC)を全ページ取り切り、未処理ノート・Tag一覧・ABC一覧を1回の応答にまとめる。30秒だけ使い回す
3 本文の取り出しと自動要約 ›
選んだノートのNotion本文を先頭12,000文字まで取り出し、ブラウザ側で重要な4文を抜き出して要約にする。AIは使わない
4 原典プレビュー ›
本文が無いときだけ動く代役。リンク先のHTMLをサーバーが読みに行って要約する。X投稿だけはブラウザがX公式の埋め込みで表示する
決める ― 行き先を2段階で選ぶ
5 Tagの推薦と新規作成 ›
ノートの文とTag名を2文字の並びに刻んで重なりを数え、上位3件をおすすめとして出す。全部ブラウザ内の計算
新しいTagを作るときだけ書き込みが起きる
6 ABC Note候補の絞り込みと下読み ›
選んだTagにぶら下がるABC Noteだけを候補にし、上位9件の本文の見出しをサーバーが下読みして、並び順を付け直す
書く ― Notionへ実際に反映する
7 画像の添付 ›
コメント欄への貼り付け・ドロップで、保存より先に画像をNotionへ預ける。中身から作った64桁の指紋を、あとで二重貼りを防ぐ印に使う
8 保存:Notionへの書き込み一式 ›
このアプリの心臓部。16の検査を通してから、ABC Noteの「その他」へ見出し+コメント+元ノートへのリンクを転記し、画像を貼り、最後にLiterature Noteの4項目を書き換える。書いたあと必ず読み直して照合する
捨てる ― 保存とは別の、もう一つの出口
9 ノートの削除(ゴミ箱へ移動) ›
知識化する価値が無いと判断した1件を、Notionのゴミ箱へ移す。本当に消すのではなく、復元できる状態にする
別の画面 ― 受信箱を離れて全体を見る
10 全体マップと「サブ埋没」判定 ›
Tag → ABC Note → Literature Note の木を丸ごと描く読み取り専用の画面。「関連としては繋がっているのに、本文からは1度も引かれていない」ノートを、本文を走査して炙り出す
11 再構成ラボ(実験版) ›
育ったABC Noteの中身を、カードの並べ替えで組み直す試作。対象は題名が「[TEST・削除可]」で始まる1ページだけに固定されている
本番のノートには触れない安全装置つき
この2つだけが、アプリの外にある
Notion(正本)
3つのDBとページ本文。アプリ側に自前の保存先は無い
外部の記事サイト
読み取り専用。4番だけが、公開ページを1回だけ取りに行く
土台 ― 1〜11の下と中にあるもの
12 画面の組み立てと配信 ›
1番より前にある土台。枠だけのHTMLを返し、中身は空のまま渡す
13 入力の受け止めと候補更新の手動化 ›
3番と8番の間で動く編集欄。推薦の作り直しはボタンを押したときだけ

この図から読み取れること

システムの骨組み

APIの一覧(全12本)

すべて /api/ の下にあり、すべて 1番の門を通る。画面のHTMLはサーバーで組み立てるが、 中身のデータはこの12本を通してブラウザが取りに行く。

メソッドとパス受け取る形式返す形式主なステータスコード担当
GET /api/bootstrapクエリ文字列 ?noteId=(任意)application/json200 / 400 / 401 / 404 / 4292番
GET /api/notes/{id}application/json200 / 400 / 401 / 4043番
DELETE /api/notes/{id}application/json200 / 400 / 401 / 409 / 5029番
POST /api/source-previewapplication/jsonapplication/json200 / 400 / 4014番
POST /api/tagsapplication/jsonapplication/json200 / 400 / 401 / 5025番
POST /api/candidate-contentapplication/jsonapplication/json200 / 400 / 401 / 4296番
POST /api/uploadsmultipart/form-dataapplication/json200 / 400 / 401 / 5027番
POST /api/processapplication/jsonapplication/json200 / 400 / 401 / 409 / 5028番
GET /api/mapapplication/json200 / 401 / 404 / 42910番
POST /api/map/sub-buriedapplication/jsonapplication/json200 / 400 / 40110番
GET /api/lab/recomposeapplication/json200 / 401 / 40911番
POST /api/lab/recomposeapplication/jsonapplication/json200 / 400 / 401 / 409 / 50211番

コードの意味の使い分け。 400=送られてきた中身が形として間違っている。 401=あなたが誰か分からない(サインインしていない)。 404=Notion側で対象が見つからない、または連携に共有されていない。 409=形は正しいが、いまのNotionの状態と噛み合わない(すでに処理済み、開いてから変わった、など)。 429=Notionへの要求が多すぎる。 502=書いたあとの照合が合わなかった。 503=Notionの接続情報(トークン)が設定されていない。

特徴的なのは、Notionが返したコードがそのまま利用者側の応答コードになること。 Notionが 429 を返せばアプリも 429 を返し、404 を返せばアプリも 404 を返す。 「Notionの状態をそのまま伝える」という方針が、コードの選び方にも出ている。

認証のしくみ

外部へ出ていく通信は3方向だけ

相手誰が呼ぶか送るもの受け取るもの歯止め
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)の埋め込み配信ブラウザ(サーバーは介さない) スクリプトの読み込み要求 投稿の表示部品 追跡拒否の指定を付ける。読めなければ原典リンクだけを出す

Notion側のデータの形(このアプリが前提にしている構造)

覚えておく期間(キャッシュ)

何をどこで有効期間何が変わると捨てるか
受信箱の一式(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秒キャッシュが効く」のは運が良ければ、という程度に読むのが正しい。 正しさはキャッシュに依存せず、書き込み前の再取得と書き込み後の照合で担保している。

同時に触ってしまったときの守り

未確認事項

※ この図は、2026年8月14日時点の zettelkasten-inbox のプログラムを読んで作成しました。過去の設計資料は参照せず、いま動いているコードだけを根拠にしています。

※ 番号は処理の流れに沿って 1 から新しく振っています。同じアプリの別の解説資料とは番号が対応しません。

※ 抽象度は Lv.4 で統一しています。通信の方式・データの形式・認証のしくみ・ステータスコードまでは書き、製品名やライブラリ名、関数名やファイルの場所までは踏み込みません(そこは Lv.5)。

ブロック詳細の目次へ →

akuramochi1.com — personal tools for learning and thinking.