このリポジトリは、設計レビュー勉強会イベント「実践!ミノ駆動さんにAI製のサービスを叩き直してもらった」のレビュー対象サービスとして、ほぼ全てをバイブコーディングで実装したものです。このREADME.mdでは、実装方法においての情報や、サービスの機能仕様、設計、ローカルでの動作確認の手順などをまとめています。
イベントアーカイブを見ながら指摘箇所などを見比べて見るために公開しております。Java/Spring Bootの参照実装ではありませんのでご注意ください。また、ミノ駆動さんの修正前のものになります。
イベントはこちら https://lapras.com/events/60
本リポジトリでは Issue 機能等をオフにしています。フィードバック・お問い合わせは LAPRAS のチャットサポート、または ユーザーコミュニティ までお願いいたします。
詳しくは ./main.md に記載しております。
実装後に画面の動きをベースに、不具合や画面の動線、Loading表示などの体験面のフィードバックを何度か送り、完成させました。 また、実装最終段階で Java/SpringBoot の一般的な実装方法と大きな乖離がないことをチェックさせています(大きな修正はありませんでした)。
Salonify はオンラインサロン・プラットフォームです。 誰でもサロンを開設して会員を募集し、会員は月額プランに加入してコンテンツとコミュニティに参加できます。Java 21 / Spring Boot 製、サーバーサイドレンダリングの Web アプリで、コードレビュー実演イベント用のデモとして作られています。
主な機能:
- サロン開設・運営: サロン作成・編集、複数の料金プラン(トライアル・初月割引)、公開 / 招待 URL 限定
- プラン課金・入退会: プラン選択・変更・退会、請求履歴(決済はデフォルトでモック。詳細は後述)
- 会員限定投稿: Markdown 投稿、画像アップロード、プラン限定公開、下書き、ピン留め、いいね、YouTube 埋め込み
- 掲示板: スレッド、コメント(1 段ネスト)、いいね、通報、ページネーション
- 運営ダッシュボード(オーナー): 売上見込み・会員数、会員管理、招待 URL 管理、売上・振込申請
- プラットフォーム管理(管理者): ユーザー管理(検索・停止・管理者付与)、サロン管理、通報管理
登場ロールは ゲスト / 会員 / サロンオーナー / プラットフォーム管理者 の 4 種です。
このアプリが何であるかを、機能ごとの実装状況(本物 / モック / 未実装)や意図的な「奇妙な仕様」まで含めて詳しく知りたい場合は
docs/OVERVIEW.mdを参照してください。
必要なもの: Docker のみ(Java/Maven はホストに不要。ビルドはコンテナ内で行います)。
docker compose up --build- DB(PostgreSQL 16)起動 → スキーマ自動反映 → シードデータ投入 → アプリ起動まで自動で行われます。
- 起動後、http://localhost:8080 にアクセスできます。
停止・データ初期化:
docker compose down # 停止(データは保持)
docker compose down -v # 停止 + DB/アップロードを完全初期化| メール | パスワード | 役割 |
|---|---|---|
| salonify-owner@example.com | password123 | サロンオーナー(「テック起業ラボ」を運営) |
| salonify-member@example.com | password123 | メンバー(「ライト」プランに加入中) |
| salonify-admin@example.com | password123 | プラットフォーム管理者 |
- 認証: メール認証付き新規登録 / ログイン / パスワードリセット(JWT Cookie セッション、BCrypt)
- サロン: 開設・編集、公開 / 招待URL限定、複数プラン(トライアル・初月割引)
- 入会・退会: プラン選択・変更、請求履歴(決済はモック)
- 投稿: Markdown 投稿、画像アップロード、プラン限定公開、下書き、ピン留め、いいね、YouTube 埋め込み
- 掲示板: スレッド、コメント(1段ネスト)、いいね、通報、ページネーション
- オーナー: ダッシュボード(売上見込み・会員数)、会員管理、招待URL管理、売上・振込申請
- 管理者: ユーザー管理(検索・停止・管理者付与)、サロン管理(削除)、通報管理
外部サービス(決済・メール・画像ストレージ)にはデフォルトで接続せず、ローカルで完結します。
| 機能 | このアプリでの挙動 |
|---|---|
| メール送信 | 送信されません。認証コード・リセットコードは認証画面に直接表示され、アプリログにも出力されます |
| 決済(入会) | STRIPE_SECRET_KEY 未設定時は Stripe を使わず即入会します。初回分の請求レコードのみ記録されます(実際の課金なし) |
| 振込申請(payout) | 何も処理されません(成功メッセージのみ)。手数料計算(5%)だけ実装されています |
| 画像アップロード | クラウドではなくコンテナ内 /app/uploads(docker volume)に保存し、/uploads/** で配信します |
定期課金バッチは存在しません。入会後の再請求は発生しません。
STRIPE_SECRET_KEY の有無で入会フローが切り替わります。
- 未設定(デフォルト): 上記のとおり、Stripe を使わず即入会します。
- 設定時: テストキー(
sk_test_...)を渡して起動すると、入会ボタン押下時に Stripe Checkout(テストモード)へ遷移します。テストカード番号4242 4242 4242 4242(有効期限・CVC は任意の未来日・任意の3桁)で決済すると入会が確定します。Webhook・継続課金・解約時のStripe側同期は対象外です。
STRIPE_SECRET_KEY=sk_test_... docker compose up --buildJava 21 / Spring Boot 3.5(Spring MVC + Thymeleaf、サーバーサイドレンダリング)/ Spring Data JPA (Hibernate) / PostgreSQL 16 / JWT (jjwt) / BCrypt (spring-security-crypto) / commonmark。 認証・認可は Spring Security フィルタチェーンを使わず、JWT Cookie + Interceptor + ガードで自前実装しています。
Docker のみで実行する場合:
docker run --rm -v "$PWD/app":/build -w /build maven:3.9-eclipse-temurin-21 mvn testホストに Java 21 がある場合は cd app && ./mvnw test でも実行できます。
ユニットテスト(手数料計算・HTMLサニタイズ・レート制限・投稿可視性・フォーム処理)を含みます。
app/ # Spring Boot アプリ
├── src/main/java/com/example/salonify/
│ ├── controller/ # 画面・APIコントローラ
│ ├── entity/ # JPAエンティティ(14テーブル)+ ステータス等の定数クラス
│ ├── repository/ # Spring Data リポジトリ
│ ├── service/ # 入会・売上集計・招待・サロン削除・表示組み立て
│ ├── support/ # 認証/セッション/サニタイズ/レート制限/決済 等
│ ├── config/ # Interceptor登録・シード投入
│ └── web/ # 例外・リダイレクト・共通モデル
│ └── resources/templates/ # Thymeleaf
docker-compose.yml # DB + アプリ
docs/OVERVIEW.md— このアプリが何か(ロール・機能ごとの実装状況・意図的な奇妙な仕様・要件との食い違い)docs/reference/requirements.md— 要件定義docs/instructions/— 実装仕様(データモデル・全エンドポイント・全画面)
このリポジトリは元々、Next.js 製の参照実装(refs/ サブモジュール)と同じ仕様を Java / Spring Boot で書き起こしたものです。上記の「奇妙な仕様」やモックの挙動は、その参照実装の挙動を意図的に踏襲した結果です。参照実装を知らなくても本 README と docs/OVERVIEW.md だけで内容は把握できます。