「本当に全部終わったのか」を疑ってNotionアーカイブを実物照合した日

開発misc-dev

「本当に全部終わったのか」を疑ってNotionアーカイブを実物照合した日

Notion の中身を丸ごとローカルに落とすアーカイブ作業を、しばらく放置していた。 久しぶりに開いて、まず進捗がどこまで進んでいるのか自分でも分からなかったので、ディレクトリの実態を確認させるところから始めた。

10日分のコミットが宙に浮いていた

「PLAN.md と runs ディレクトリを見て、今どうなっているか教えて」とだけ投げた。 返ってきた答えは、データ作業自体は全量終わっている、ただしコミットが7月16日から止まっている、というものだった。

8,718 ファイルがステージされたまま、10日間そこに座っていた。 学習ゲートのクイズに答えないまま席を立ったのが原因だった。今日はクイズをスキップして通した。

ここまでは事務作業だ。コミットして、push して、これで終わり——のはずだった。

完了報告は、ディスクの中を見ているだけだ

ただ、push のコマンドを打たせながら、引っかかるものがあった。 「本当に全部終わったのか」を判定している材料が、全部こちら側のディスクにしかない。 manifest が 9,375 件あり、ユニークID も 9,375 件で整合している——それは「取ってきたものが 9,375 件あった」の証明にはなるが、「Notion 側に 9,375 件しかなかった」の証明にはならない。

なので、コミットと push を投げたあとに条件を1つ足した。 ブラウザで Notion の実物を開いて、向こう側と突き合わせてほしい、と。

一覧を取る経路がなかったので、画面から数えさせた

向こう側の全体像を取るなら検索 API を叩くのが早い、と最初は考えた。 実際に叩かせたら、リクエストの形式が合わずに何も返ってこない。探索系の内部エンドポイントもいくつか試させたが、揃って 404 だった。

ここで「Notion 側の一覧は取れません」と結論にされていたら、照合そのものが流れていた。 そうはさせずに、ブラウザで開いている画面そのものから読み取る方針に切り替えさせた。人間が目で数えられるものは、DOM からも数えられる。サイドバーに並んでいるリンクを列挙させて、それをローカルの manifest と突き合わせる。

欠落に見えたものの、ほとんどは欠落ではなかった

こうして出てきた照合の結果は、期待していたよりずっと具体的だった。

サイドバーに並んでいるリンクは 74 件。そのうち 73 件はローカルに存在していた。 残る 1 件を追いかけると、クロールの起点にしていたルート一覧に親が含まれていないページで、そこから枝が伸びていなかったと分かった。中身を開かせたら、実体としてのデータを持たない集約ビューだった。取れていないのではなく、取るべき実体がなかった。

ページの木構造を辿り直させたときには 49 件が欠落として出た。 そのうち 48 件は、データベースを本文中に埋め込んで表示するためのビューのブロックで、そもそも Markdown に変換する対象ではない設計だった。生ブロックの台帳には全部残っている。

行数の突き合わせも、数が合わないところで止めずに詰めさせた。 大きめのデータベースを 6 件選んで Notion 側の行数と比べたら、ローカルのほうが多いものがあった。数の比較では判定できないので、行の ID 集合で厳密に照合し直させた。4 つのデータベース・1,391 行、欠落ゼロ。

本当に取れていなかったのは、Notion が最初から用意している組み込みのページだった。開かせてみると、ウィジェットが並んでいるだけで、書いた内容は1文字も入っていなかった。

取得は完全、Markdown は不完全

ここまでで安心しかけたところに、別種の抜けが出てきた。

Markdown の側とブラウザ表示を1ページずつ見比べさせたら、構造としては一致している。 ただ、本文に入れていたテーブルが Markdown に落ちていない。生ブロックには 17 行のテーブル実データが残っているのに、変換後のファイルには行が出てこない。未対応ブロックとして記録されていたテーブルは 659 件あった。

ページのプロパティも同じだった。一覧で並べたときに見えている列の値が、本文には現れていない。

プロパティのほうは、抜けていると分かっただけでは直せない。値だけ復元できても、それが何の列の値なのかが分からなければ意味がないからだ。列名を保持しているスキーマが生データ側に残っているかどうかまで確認させて、復元の見込みがあることを先に押さえた。

「全部終わった」は半分正しくて半分間違っていた、という結論になった。 Notion からの取得は完全に近い。取ってきたものを Markdown に変換する側に、まだ通っていない経路が2つある。

どのページのテーブルが落ちているのかを、リストで出させた

抜けの存在が分かっても、それだけでは明日の手が動かない。 「どのページのテーブルが取得できていないのか、サンプルでいいからリストにして」と頼んだ。中身を自分の目で見ないと、テーブルから直すべきかどうかも決められない。

抽出は 480 件で返ってきた。Markdown 側のコメントとして残っている数は 659 件で、合わない。 ここも数が合わないまま報告させずに、差分がどこから来ているのかを確認させて整合を取った。

画像はどうなっているのか

締めようとしたところで、もう1つ気になった。貼り付けた画像は全部取れているのか。

記録の上では取得済みになっている。ただ、今日ここまでで学んだのは、記録は取得の証明にならないということだった。 なので「記録だけで答えないで、実データで確認して」と言い直した。

失敗として記録されている 115 件の URL は manifest に載っていない。生ブロックから実 URL を引いて突き合わせさせた。 実体ファイルは 5,305 件、すべてディスク上に存在していた。

そのうえで、以前に作ってあったビューアを実際に起動させて表示まで確認した。 9,375 ページすべてが開き、画像もローカルの実体から描画されていた。ブラウザに自分のスクリーンショットが並んでいるのを見て、ようやく納得した。数字で「存在します」と言われるより、画面に出ているほうが早い。

記録に残して、明日に回した

最後に、今日確かめた事実を PLAN.md に書き残させた。 何を照合したか、どの数字がどう合ったか、合わなかったものは何だったか。次に開いたときの自分が、また「進捗どうなってる?」から始めなくて済むように。

結果として、今日のコミットは2本になった。10日間ぶら下がっていたアーカイブ本体と、それが本当に取り切れているかを確かめた検証の記録。どちらも push まで通して、作業ツリーは空になった。

次にやる候補も並べさせた。順番としてはテーブルの変換からになりそうだ。抽出リストはもう手元にあるので、明日はそこから開ける。

今日の学び

  • 完了報告は、報告している側の視界の中でしか完了していない。 manifest とディスクだけで「全部取れた」と言えるのは、ローカルの整合性までだ。向こう側の実物を開いて数を数えるまで、取り切れたかどうかは分からない
  • 数が合わないときに「たぶん大丈夫」で流さない。 行数が一致しないデータベースは、ID 集合で照合し直したら欠落ゼロだった。逆に、数が合っていても中身が落ちているケース(テーブル)もあった。数の一致と中身の一致は別の話
  • 「欠落」と出たものは、まず正体を見る。 49 件のうち 48 件は、変換対象ですらないブロックだった。ここで慌てて再クロールしていたら、丸一日溶けていた
  • 自分の目で画面を見るのが一番速い。 画像 5,305 件が存在すると言われても半信半疑だったが、ビューアを立ち上げてページが開いた瞬間に判断がついた
#Notion#アーカイブ #データ検証 #Claude Code#整合性チェック