Zettelkasten Inbox / ブロック詳細
Notionの3つのデータベースを1ページも残さず取り切り、未処理ノート・Tag・ABC Noteの3つの一覧を1回で返す、いちばん重い読み取り。ここで全部渡すから、このあとの選択操作は通信なしで動く。
抽象度 Lv.4(技術用語+システム上のやりとりまで/製品名・ライブラリ名は書かない)受信箱の画面を開いたときに1回だけ走る、いちばん重い読み取り。 Notionの3つのデータベースを全部、1ページも残さず取り切って、 「未処理のノート一覧」「Tagの一覧」「ABC Noteの一覧」を1回の応答にまとめて返す。
ここで全部まとめて返してしまうのがこのアプリの根っこの設計で、 このあとTagを選んでもABC Noteを絞り込んでも、サーバーへの問い合わせは発生しない。 選択操作はすべてブラウザの中のデータで完結する。だから最初が重く、そのあとが軽い。
1. アクセス確認 → 2. 受信箱の初期読込 → 3. 本文の取り出し/5. Tagの推薦/6. ABC候補
noteId(全体マップから修正しに来たときだけ付く)GET /api/bootstrap。詳しくは5章の各工程に書いたnoteId が付いていれば、32桁の16進または 8-4-4-4-12 のハイフン付きの形かを正規表現で検査し、外れたら 400Cache-Control: no-store を付け、ブラウザに保存させないここより後ろに分割できない理由。「Tagを選ぶ → その配下のABC Noteだけを候補にする」という このアプリの中心の動きを成立させるには、TagとABC Noteの親子関係が最初から手元に揃っている必要がある。 Tagを選んでから配下を問い合わせる作りにすると、Tagを付け外しするたびに通信が走り、 「あれこれ試しながら決める」という使い方ができなくなる。
ここより前に置けないもの。未処理の定義(タグ欄もABC欄も空)はNotion側の絞り込みで表現されている。 全部取ってからアプリ側で選り分けるのではなく、Notionに絞り込ませてから受け取る。 受信箱に出るのは数十件でも、Literature DB全体は数百件あるため、この差は通信量に直接効く。
30秒という控えの長さ。短すぎるようだが、 保存・削除・Tag作成が起きたときは時間に関係なく即座に捨てられる。 つまり30秒は「自分の操作以外でNotion側が変わった場合に、どれだけ古い情報を見せてよいか」の上限であって、 自分の操作は必ず即時に反映される。
| 工程 | 主体 | やりとりの内容 | 方向 |
|---|---|---|---|
| 2-1 | ブラウザ → 初期読込API | 画面表示の要求(+ 修正対象のID) | → |
| 2-2 | 初期読込API(内部) | IDの形の検査 | ↻ |
| 2-3 | 初期読込API → メモリの控え | 30秒以内の控えの有無を確認 | → |
| 2-4 | 初期読込API → Notion | Literature DBを条件つきで全件取得 | → |
| 2-5 | 初期読込API → Notion | Tag DBを全件取得 | → |
| 2-6 | 初期読込API → Notion | ABC DBを全件取得 | → |
| 2-7 | 初期読込API(内部) | 3つを突き合わせ、説明文と並び順を作る | ↻ |
| 2-8 | 初期読込API → メモリの控え | 30秒の期限つきで保存 | → |
| 2-9 | 初期読込API → Notion | (修正モード時)対象1件と全関連の取得 | → |
| 2-10 | 初期読込API → ブラウザ | 3つの一覧+取得時刻 | ← |
2-1 画面が開くと、ブラウザはまず「いま何が溜まっているか」を丸ごと問い合わせる。 全体マップから「このノートを直したい」と飛んできた場合だけ、URLに対象の番号が付いてくる。
技術的には GET /api/bootstrap、
修正モードなら GET /api/bootstrap?noteId=…。
対象の指定を本文ではなくクエリ文字列に載せているのは、これが読み取りの要求だから。
画面側のURLは /?note=… で、そこから取り出してAPIへ渡している。
2-2 番号が付いていたら、まず形だけを確かめる。中身がNotionにあるかどうかは、まだ見ない。
技術的には 32桁の16進、または
8-4-4-4-12 のハイフン区切り、のどちらかに正規表現で一致するかを見る。
外れたら 400 と「全体マップから開き直してください。」を返す。
通ったら、ハイフンを一度全部外してから決まった位置に入れ直す正規化をする。
Notionは両方の表記を受け付けるので、同じページを2つの別物として数えてしまう事故を防ぐため、
このアプリの中では常にハイフン付きの形に揃えている。
2-3 直前の30秒以内に誰かが同じ問い合わせをしていたら、その結果をそのまま使い回す。 Notionへは行かない。
技術的には サーバーのメモリ上の変数に 「有効期限の時刻」と「中身」を持っているだけの、いちばん単純な形の使い回し。 ディスクにも外部にも書かない。実行環境が入れ替わると消えるので、 これは速さのための工夫であって、正しさを支える仕組みではない。
2-4 Notionへ「タグもABC Noteも付いていないノートを、新しい順に全部ください」と頼む。 これが受信箱に並ぶ中身になる。
技術的には POST /v1/data_sources/{id}/query に
and でつないだ2つの条件(関連が空・関連が空)と、作成時刻の降順の並び指定を application/json で送る。
読み取りなのにPOSTなのはNotion側の仕様で、絞り込み条件をJSONで送るため。
Notionは1回に最大100件しか返さないので、「続きの目印」が返ってくる限り繰り返し呼ぶ
(ページ送り)。件数の上限は設けていないので、対象が1,000件あれば10回往復する。
2-5 続けてTagの一覧を、条件なしで全部もらう。
技術的には 同じ形の要求を、絞り込み条件なしで投げる。 ここで一緒に受け取るのが「親アイテム」(Tagの階層)と「Out_Permanent」(配下のABC Note)と 「Number_In_Literature」(何件のノートに使われたかの集計値)。 集計値はNotion側が計算して返すので、アプリは数え直さない。
2-6 最後にABC Note(知識ページ)の一覧を、最近さわった順で全部もらう。
技術的には 2-4・2-5・2-6 は同時ではなく、1つずつ順番に実行される。 3つは互いに依存していないので同時に投げることもできる(実際、全体マップの10番はそうしている)。 ここが直列なのは、Notion側の1秒あたりの要求数の制限に当たりにくくするためと読める。 そのぶん、初回の待ち時間は3つの合計になる。
2-7 3つの一覧を突き合わせて、画面がそのまま表示できる形に組み替える。 Tagには「このTagの主なABC Noteはこれ」という説明文が付き、よく使われるTagが上に来る。
技術的には TagのIDとABC Noteの題名を対応表(辞書)にしてから引き当てるので、 突き合わせは件数に比例する時間で終わる(総当たりにはしない)。 並び順は使用回数の降順、同数なら題名の日本語順。 題名の比較は日本語の並び順を指定して行う――指定しないと、 ひらがな・カタカナ・漢字の順が環境によって変わるため。
2-8 組み上がった一式を、30秒だけ覚えておく。
技術的には 「いまの時刻+30秒」を期限として保持する。 保存(8番)・削除(9番)・Tag作成(5番)が成功したときは、 期限を待たずにその場で捨てる関数が呼ばれる。 同じ関数が全体マップの5分の控えも一緒に捨てる。
2-9 全体マップから修正しに来たときだけ、その1件を個別に取り直して、 いま何のTagと何のABC Noteに結び付いているかを完全に把握する。
技術的には まず単体のページ取得。
ゴミ箱に入っていないか、本当にLiterature DBの下にあるかを確認し、違えば 400。
次に関連づけを全部たどる。ページ取得の応答には関連が最大25件しか入らず、
「まだ続きがある」という印だけが立つので、続きは専用の問い合わせで100件ずつ取り切る。
タグ側とABC側の2つを同時に取りに行く(ここだけは並行)。
この「開いた時点の完全な状態」が、8番で「開いてから変わっていないか」を判定する材料になる。
2-10 最後に、3つの一覧と取得時刻をまとめて返す。 ブラウザには「この応答は保存しないで」と伝える。
技術的には 200 + application/json +
Cache-Control: no-store。ブラウザ側の fetch も
保存しない指定で呼んでいるので、二重に保存を止めている。
受信箱の中身は「いま何が残っているか」そのものなので、古い写しが表示されると
処理済みのノートがもう一度出てくる。それを確実に防ぐための指定。
← 図は横にスクロールできます
400 +
「対象ノートの指定が正しくありません。全体マップから開き直してください。」。Notionへは行かない。404 を返し、それがそのまま利用者へ届く。
画面には「Notionを読み込めませんでした」と再読み込みボタン。400 +
「対象はLiterature Notes DBのノートではありません。」※ 2026年8月14〜15日時点の zettelkasten-inbox のプログラムを読んで作成しました。過去の設計資料は参照していません。
※ 番号は全体図・この解説・シーケンス図で共通です。工程番号は「ブロック番号-連番」で書いています。