1367 Words 6 min

今回は詳細設計をしていく。 と言ってもしっかりとした設計書を作るつもりはないので、最低限のデータの流れと必要なメソッドくらいを考えてみる。 記事作成時のフローは明確なので省略する

基本のフロー

graph LR
subgraph 大元のレポジトリ
A[記事作成]
end
B[記事投稿コマンド]
C[前後記事取得メソッド]
D[DB更新メソッド]
E[ファイル変換メソッド]
F[デプロイメソッド]

A --> B
B --> C
C --> B
B --> D
B --> E
E --> B
B --> F

前後記事取得メソッド

引数: カテゴリ、ファイル本体

DBから前後の記事(公開中のもの)を検索して返す

DB更新メソッド

引数: カテゴリ, slug, 下書きかどうかのフラグ

カテゴリから判断した適切な場所に、slug名と下書きかどうかのフラグを格納したオブジェクトを配置する

ファイル変換メソッド

引数: 適切な変数

各プラットフォームごとに必要な情報が違うので、それぞれのプラットフォームごとにメソッドを用意する。 適切な変数を読み取って、フロントマターに格納しつつ、本文にも前後記事へのリンクを挿入する。

デプロイメソッド gitを操作して、リモートのレポジトリにソースをpushする。その後github actionsが動いてデプロイを行うのでデプロイされる。

特殊な要件に対応したフロー

上記の基本フローは同じなのだが、今回のシステムには二つ追加要件が存在する

  1. 同一カテゴリの前後記事へのリンクを記事に挿入する
  2. zennとqiitaに投稿した記事は、2週間後に削除する

これに対応するためにはいくつか追加処理を挟む必要がある。

1. 同一カテゴリの前後記事へのリンクを挿入

これは上のフローでやってるじゃんと思われるかもしれないが、そう単純ではない。 たとえば新しく記事を追加した時を想定すると、記事本体に前回記事へのリンクを挿入するだけでなく、前回の記事にも次回記事(この例で言うところの記事本体)へのリンクを挿入しなくてはいけない。 つまりフローの中で、前後記事の更新処理を呼ばなくてはいけない。

しかしそうすると別の問題点が出てくる。 記事更新メソッド内で前後記事に対して記事更新メソッドを呼ぶことになるので無限ループしてしまう。 これには二つ対策が思いついた。

一つ目は、記事更新メソッドの引数として、副作用かどうかのフラグを持たせるというもの。

二つ目は、ほぼ同じ処理をするが、前後記事の更新メソッドを呼ばない、別メソッドを作るというもの。

今回は処理を変える可能性を考えて一つ目の方法を採用することにした。

2. zennとqiitaの投稿を2週間後に削除する

これを実現するためには別のデータベースファイルを作る必要がある。 zennとqiitaに記事を初投稿する際に、その投稿のslugと投稿日時をオブジェクトとして配列に追加し

一日一回の定期実行処理の中で、その配列の一番最初の値を見て、二週間以上前であればzennとqiitaから削除するような処理を呼ぶことにした。

気がついた弱点

カテゴリ分けしているが、zennとqiitaにはそもそもカテゴリという概念が存在しなかった。 つまり、カテゴリが違う同一slugの記事があった場合は、コンフリクトして上書きされてしまう。 最初は気をつけることで対処するが、どうせ忘れてしまう。 いづれは仕組みとして、同一slugだったら記事作成時にエラーが出るようにしなくては、、、