推薦システム構築ツールRecotemを v2.0 へ大幅にリファクタリングしました。バックエンド、フロントエンド、インフラ、CI/CD、ドキュメントまで全レイヤーを刷新し、今後もメンテナンスを続けられる状態にしています。315ファイルの変更、35,697行の追加という大規模な更新です。
リファクタリングの背景
Recotemはirspackをベースにした推薦システムのモデル構築・管理ツールです。しかし、依存ライブラリやフレームワークのバージョンが古くなり、Python 3.9、Django 3.2、Vue 2といった構成ではメンテナンスの継続が難しい状態でした。今後の開発や運用を見据えて、全面的なモダナイゼーションを実施しました。
バックエンドの刷新(Python 3.9→3.12、Django 3.2→5.1)
依存管理の近代化
requirements.txt から pyproject.toml + uv.lock(uv)に移行しました。uvによる高速な依存解決と再現性のある環境構築が可能になります。
主要ライブラリのアップグレード
| ライブラリ | 旧バージョン | 新バージョン |
|---|---|---|
| Python | 3.9 | 3.12 |
| Django | 3.2 | 5.1 |
| djangorestframework | 3.12 | 3.15 |
| celery | 5.1 | 5.4 |
| numpy | 1.19 | 2.1 |
| pandas | 1.3 | 2.2 |
| scikit-learn | 0.24 | 1.6 |
| SQLAlchemy | 1.4 | 2.0 |
| optuna | 2.10 | 4.1 |
| irspack | 0.1.16 | 0.4.0 |
| psycopg2-binary | – | psycopg[binary] v3 |
アーキテクチャの改善
- サービスレイヤーの導入:
api/services/に model、training、tuning、signing、project の各サービスを追加し、ビューからビジネスロジックを分離 - WebSocketサポート: Django Channels +
consumers.pyでリアルタイムなジョブステータス通知を実現 - ViewSetミックスイン:
OwnedResourceMixin、CreatedByResourceMixinによるオーナーシップベースのアクセス制御 - APIバージョニング:
/api/v1/のURLプレフィックスを導入 - 構造化ログ: JSON形式のログ出力とスロットルレート制御
- マイグレーション整理: 複数のマイグレーションを
0002_schema_upgradeに集約
セキュリティ強化
- HMAC-SHA256モデル署名: 学習済みモデルファイルに署名を付与し、改ざんを検知
- 安全でないファイル形式のアップロード禁止: データアップロードから安全でないシリアライゼーション形式を除外し、任意コード実行のリスクを排除
- ファイル名サニタイズ: Content-Dispositionヘッダーのファイル名をRFC 6266/5987に準拠してサニタイズ
- resign_models管理コマンド: 既存の未署名モデルファイルにHMAC署名を追加するマイグレーションコマンド
フロントエンドの完全書き換え
フロントエンドはゼロからの書き直しです。
| 項目 | 旧構成 | 新構成 |
|---|---|---|
| フレームワーク | Vue 2 + Vuetify + Options API | Vue 3.5 + PrimeVue 4 + Composition API |
| ビルドツール | webpack | Vite 6 |
| スタイリング | – | Tailwind CSS 4 |
| 状態管理 | – | Pinia + TanStack Query |
| 型システム | – | TypeScript strict mode |
| APIクライアント | openapi-generator | 手動 ofetch クライアント |
| i18n | – | 英語・日本語ロケール |
ダークモード対応や、ページベースのルーティング、コンポーザブルの活用など、Vue 3のベストプラクティスに沿った構成にしています。
インフラストラクチャの統合
Dockerの刷新
バックエンド用とCelery用で分かれていたDockerfileを、マルチステージビルドの単一Dockerfileに統合しました。非rootコンテナとしてポート8080でリッスンする構成に変更しています。
Docker Composeも5サービス構成(PostgreSQL、Redis、バックエンド、ワーカー、プロキシ)に再編成し、CI用のオーバーレイ(compose.ci.yaml)も用意しました。
nginxプロキシ
非rootのnginxをポート8000で統一的に配置し、SPA・API・WebSocket・Admin画面のリバースプロキシを一つの設定で管理します。WebSocketルートではJWTトークンがログに漏洩しないようサニタイズされたログフォーマットを使用しています。
Helmチャート
Kubernetes向けのHelmチャートにServiceAccount、PodDisruptionBudget、NetworkPolicy、HorizontalPodAutoscalerを追加し、本番運用に耐える構成にしました。
CI/CDの改善
- GitHub Actions v4/v5へのアクション更新
- CodeQLによるセキュリティスキャンの追加
- Dependabotによる依存関係の自動更新
- マルチアーキテクチャビルド + Trivyによる脆弱性スキャン
- Node.js 16→20、Python 3.8→3.12のアップグレード
テストカバレッジ
バックエンド
17の新規/更新テストファイルをpytest + pytest-djangoで整備しました。
- アクセス制御、WebSocketコンシューマー、シリアライザ、スロットル
- モデルサービス、トレーニングサービス、署名検証
- プロジェクト名のユニーク制約、ファイルミックスイン、ページネーション
フロントエンド
- 30以上のユニットテスト(Vitest)
- 10以上のE2Eテスト(Playwright)
- コンポーネント、コンポーザブル、レイアウト、ページ、ルーター、ユーティリティのテスト
ドキュメントの整備
CLAUDE.md、CONTRIBUTING.md、SECURITY.md、CODE_OF_CONDUCT.mdの追加- AWS、GCP、Kubernetes、Docker Composeのデプロイメントガイド
.env.exampleファイルによる環境変数の説明
まとめ
Recotem v2.0では、バックエンドからフロントエンド、インフラ、CI/CDまで全面的にモダナイゼーションしました。Python 3.12 + Django 5.1、Vue 3.5 + Vite 6といった最新スタックへの移行に加えて、サービスレイヤーの導入やセキュリティ強化、テストカバレッジの充実により、今後のメンテナンスや機能追加がしやすい基盤を整えました。
- PR #18: v2.0: Full-stack modernization