blog.bouzuya.net

2026-01-31 bouzuya/tsukota-web 1.0.0 をつくった

bouzuya/tsukota-web 1.0.0 をつくった。個人的な使用を意図したものなので、隠しているわけでもないがあえて URL は書かない。

tsukota-web は bouzuya/tsukota の Web 版。 tsukota は素朴な家計簿用の Android アプリ。使ったお金を記録するから tsukota 。

機能としては次のようなものがある。

  • 区分の追加・編集・削除
  • 取引の追加・編集・削除
  • アカウントの追加・削除
  • ユーザー・デバイスの追加
  • サインイン・サインアップ・サインアウト

tsukota との機能の差異は月ごとの集計機能が存在しないこと。アカウントのオーナーの招待機能がないこと。

実装。

tsukota は Android (React Native) + Firebase Auth + Firestore + Functions で、認証以外のほとんどの機能をバックエンドではなくフロントエンド (Android) 側に持たせているのが特徴的だった。

今回の tsukota-web は Cloud Run (Rust + axum) + Firestore 。フロントエンドは TypeScript + React + tailwind CSS で Cloud Run の axum から static なファイルを配信している。

永続化形式 (Firestore のドキュメント) は tsukota に互換性を持たせている。アカウントをイベントストリームとした Event Sourcing + CQRS な構成にしている。今回は User や Device も含めて Event Sourcing にしている。それらも互換性を維持して、壊さないようにしてある。 C/Q 間の連携は同一トランザクションで処理しており密に結合している。フロントエンドの構成含めて簡素化するための妥協点。

main + api + infra + application + domain で層と DI 用に crate を分割しており、 application の use case の Request / Response をそのまま api の HTTP リクエスト・レスポンスの構造とすることで層間の変換をすこし減らしてみている。

Firebase Auth の使用を避け、 signJWT API と雑な verify を自作している。なるべく構成を簡素化する方向に倒している。

AI 活用。

今回は Claude Code と GitHub Copilot CLI を使用し、なるべくソースコードを直接書かない方針をとった。ぼくは AI エージェントみたいなものには乗り遅れていて、かじってはいるものの……という状態。いまさらかもしれないが、いまさらとか言わずに、使えるようになろうというところ。

恥ずかしくはあるが記録・ふりかえりの観点で prompts/ にほとんどすべてのプロンプトを記録している。わりと雑なプロンプトを書いてしまっている自覚はある。また、このプロンプトなどを記録しようとする運用は plan mode との組み合わせがあまり良くなかった。 plan mode のファイルは ~/.claude/plans/*.md (だったかな、うろおぼえ) に出力されており、イマイチ残しづらい。プロンプトに prompts/*-plan.md に出力しろと指示してみたりはするものの、 plan mode だとファイルの読み書きはしないので……という感じ。 CLAUDE.mdAGENTS.md に出力先を書いてみたが、わりと無視されるように思う。

Claude Code の skills/ も 1 つではあるが作成してみた。 Agent Skill のドキュメントもざっと読み、どのような形式かは理解した。……とは言え、イマイチ何をどう書けばいいんだ……となっている。こちらはまだまだ活用できておらず、 2026-02 以降の課題としたい。

契約は Claude Code の Pro で契約し、どの程度で limit に到達するのかはなんとなく分かるようになった。肌感ではあるが、 1 日まるっと書くような用途だと Pro では厳しそうだ。 1h 程度動かしていると current session limit に到達するし、それを朝晩やると週の終わりまで届かずに weekly limit にも到達する。 2026-01 は読書の記録 (2026-01-22) などもあり、 100% 使い切ったという感じはないが、素朴には使えたかなという形。 limit 到達時は GitHub Copilot CLI を使用した。 UI は寄せられているが、 model を揃えてもイマイチ賢くない感じがするのはなぜだろう。

出力されるコードのクオリティについては、動くコードは書いてくれる。が、個人的には満足の行くクオリティではなく、ちょっとずつ意図とズレたコードになりがち。このあたりは意図をうまく伝えたり、設定すればやってくれるんじゃないか、ぼくの使い方が悪い部分もあるんじゃないかと思っている。あとこのあたりのコードへのこだわりのない層であれば vibe coding とか言いたくなるのはそうだろうなと感じた。

AI 任せで書いてくれる (自分で書かない) ので苦にならない。投げにくい。……が楽しみも奪われている感じはする。もうすこし言えば楽しさの方向性が変わっている感じ。コードをコツコツ書いてつくるみたいな楽しさは損なわれている。動くものをつくれるという楽しさはある。しきいが下がっている。このあたりの印象は今回の取り組みの前後であまり変わらない。繰り返し肯定的な側面で言うと「やり切る」「つくり切る」の難易度がかなり下がっているので、良くも悪くも、より多くの (能力の低いも含む) 人が、いろいろつくれるようになるものだなと思う。老害ぽいことを言うなら教育上悪そうだなと思う。よく分からなくてもなんとなく動くものができるのはわりと危険なように思う。

まだまだ使い込みが足りない・効率化できると感じる。プロンプト→コード生成待ち→レビュー→プロンプト……みたいな素朴なサイクルでやってみたが、コード生成待ちには次のことができると思うし、レビューしている間も働かせられると思う。並行度が足りていないと感じた。 git worktree を使うなどして変更が衝突しないようにし、並行度を上げれば効率は上がると思う。このあたりも 2026-02 では試していきたいところ。一方でさらに limit が厳しく感じられそうだ。

目標の達成状況。

ひとまず 2026-01 の目標 (2026-01-12) は達成できたものとしたい。来月の準備ができていないので、来月は厳しそうな気がしている。無理をしない形に見直す必要があるかもしれない。


体調不良。ずっと微熱で、寒気と喉の痛みを感じている。昼から横になっていた。つらい。


今日のコミット。