釣り人のための「パーソナルOS」を目指した個人開発の Web サービス。釣果の記録から、AI による魚種判定、データ分析、ブログ投稿までを一つの場所にまとめている。
主な機能
- 釣果の記録(魚種・場所・日時・写真)
- TensorFlow.js による魚種のAI判定
- 釣果データの可視化・分析
- ブログ投稿
技術構成
- フロントエンド: Next.js / React / TypeScript / Tailwind CSS
- バックエンド: Go / PostgreSQL
- 機械学習: Python / TensorFlow(魚種分類モデル)
- インフラ: Google Cloud / Firebase
ディレクトリ設計
バックエンド・フロントエンド・機械学習を独立したサブディレクトリで持つモノレポ構成。
tsurite/
├── tsurite-api/ # Go バックエンド(クリーンアーキテクチャ)
│ ├── cmd/ # エントリポイント(APIサーバー・CLIツール)
│ ├── internal/
│ │ ├── domain/ # エンティティ・Repositoryインターフェース(最内層)
│ │ ├── usecase/ # ユースケース
│ │ ├── interfaces/ # HTTPハンドラ・ミドルウェア・ルーター
│ │ └── infrastructure/ # DB・外部APIの具体実装
│ ├── migrations/ # DBマイグレーション
│ └── openapi/ # openapi.yaml(API仕様の正典)
├── tsurite-web/ # Next.js フロントエンド
│ ├── app/ # App Router のページ
│ ├── components/ # atoms / molecules / organisms(+ shadcn/ui)
│ └── lib/ # フック・APIクライアント・ユーティリティ
├── tsurite-ml/ # 魚種分類モデル(Python → TensorFlow.js)
│ └── scripts/ # 学習・エクスポート・検証パイプライン
├── docs/ # 設計書・アーキテクチャメモ
└── scripts/ # pre-push フックなど共通スクリプト
- バックエンドはクリーンアーキテクチャ。依存の向きを内側一方向(インターフェース → ユースケース → ドメイン ← インフラ)に固定し、ドメインロジックを外部都合から分離。ORM を使わず生 SQL で DB アクセスを明示的に管理する。
- API First。
openapi.yamlを単一の正典とし、サーバースタブを自動生成して API と UI の契約を常に一致させる。 - フロントエンドは Atomic Design + Container/Presentation 分離。データフェッチを Container に閉じ込め、描画コンポーネントは純粋に保つ。
- ML はブラウザ完結。学習済みモデルを TensorFlow.js にエクスポートし、魚種判定をクライアントサイドで動かす。
- フロントと API を別ホストするステートレスな2層構成(Google Cloud / Firebase に集約)で、将来のアプリ展開に向けた拡張余地を設計段階から確保している。
テスト・品質保証
「設計どおりに保たれているか」を機械で担保することを重視している。
- バックエンドは約1,000のテスト関数(Go)。各層をテストで検証し、リグレッションを防ぐ。
- フロントエンドはテストピラミッドを意識した構成。コンポーネント・フック・ユーティリティの単体テスト約150本を土台に、ページ単位+データ取得(hooks)の integration テスト17本を重ね、Playwright の E2E は重要導線2本(釣行一覧→詳細→ホーム/釣行詳細→ブログ記事の自動生成)に絞る。高コストな E2E を広げず、検証を下の層に寄せる判断。
- アーキテクチャ自体をテストする。
architecture_test.goで依存の向き(ドメイン層が外側を import しない等)を Fitness Function として固定し、設計ルール違反を CI で機械的に落とす。 - DB は ORM を使わず生 SQL + goose マイグレーションで状態遷移を明示。スポット管理は PostGIS の地理空間クエリで扱う。
- API には CORS・レートリミットを実装。
AI ガードレール方針
AI コーディングアシスタント(主に Claude Code)を多用するため、「ルールベースのチェックで安く先に弾き、LLM レビューは補完に回す」という方針を採っている。CLAUDE.md に規約を集約してガイドし、pre-push フックや静的解析・アーキテクチャの Fitness Function で機械的に検知。LLM レビューはその追加層と位置づけている。根底にあるのは「問題が起きたらコードだけ直さず、harness(規約・lint・スクリプト)側にルールを刻む」という姿勢。



