ほしのディップアート様 オンライン会員システム
手芸(ディップアート)レッスンのオンライン会員制動画配信プラットフォームです。 対面レッスンからオンラインへの転換を実現し、時間・場所の制約を超えた全国集客を可能にしました。 要件定義・UI/UXデザイン・実装・運用までを 1 人で担当しています。

- ジャンル
- Webシステム
- 制作期間
- 2ヶ月
- 納品日
- 2026.03
プロジェクト概要
項目 | 内容 |
|---|---|
プロジェクト形態 | 個人クライアントワーク(B2B 受託) |
規模 | TypeScript/TSXファイル 127本 / 約16,000 行、コミット数 130+ |
チーム構成 | 1 名(要件定義・デザイン・実装・デプロイ・運用) |
役割 | フルスタックエンジニア 兼 UI/UXデザイナー 兼 PM |
背景・課題
クライアントは対面のディップアート教室を運営しています。受講者を全国に拡大したいというニーズがありましたが、ZoomやYouTube では「会員制」「閲覧期限管理」「申込者との突合」を実現できません。
SaaS製品(UTAGE 等)では業務フローに合わず、月額コストも事業規模に対して重い状況でした。
解決方針
専用Webアプリを構築しました。Vimeoを動画配信基盤、Supabaseをデータ・認証基盤に据えることで運用コストを最小化しつつ、業務特有の要件(管理名と表示名の二重管理、コース/レッスン2階層の閲覧期限管理など)に最適化した実装を提供しています。
技術スタック
フロントエンド
- Next.js 16 (App Router) — Server Components / Server Actions を活用
- React 19
- TypeScript 5 — 厳密な型付け、
anyは原則禁止 - Tailwind CSS v4 — デザインシステム的にカラー・フォントを集約
バックエンド / インフラ
- Supabase (PostgreSQL / Auth / Storage / Row Level Security)
- Vercel (Hosting / Edge Functions / Cron Jobs)
- microCMS — ナレッジ記事のヘッドレス CMS
外部連携
- Vimeo — 動画埋め込み配信(DRM不要のクローズド配信)
- Google OAuth (Supabase Auth 経由)
主要ライブラリ
@supabase/ssr— Server Components 対応の認証クライアント@dnd-kit— コース・レッスンの並び替え D&Dbrowser-image-compression— クライアントサイド画像圧縮isomorphic-dompurify— リッチテキストのサニタイズreact-hot-toast— トースト通知microcms-js-sdk
技術的なハイライト
1. 2階層の閲覧期限管理とアクセス制御
ビジネス要件として、コース単位と「レッスン個別」両方の閲覧期限を管理する必要がありました(例: 通常はコース受講だが、特定レッスンだけ追加購入で延長させたいケース)。
アクセス判定ロジックは複数画面に分散しがちなため、ピュアヘルパー関数 evaluateLessonAccess() に集約し、サーバーサイド3関数(DBアクセスあり)とUI表示用1関数で同じルールを共有する設計としました。
// アクセス制御ルール(レッスン個別受講がコース受講をオーバーライド):
// - user_lessons が存在 → user_lessons.expires_at のみで判定(null = 無期限)
// - user_lessons が無い → user_courses.expires_at で判定判定結果として「アクセス可否」と「表示用期限日」の両方を返すAPI設計により、各ページのバッジ表示(期限切れ / 残り N日 / 無期限)も一貫性を保てるようにしています。
2. Row Level Security (RLS) によるセキュリティ
SupabaseのRLSを活用し、生徒が自分の受講コース以外を取得できないことをDBレベルで担保しています。アプリケーションコードに不具合があってもデータが漏れない設計です。
- 生徒: 自分の
user_courses/user_lessons/notificationsのみ閲覧可 - 講師: 全コース・レッスンの編集可
- 管理者: ユーザー管理含む全権限
期限切れデータの一部取得が必要なケースでは、createAdminClient() でサービスロールキーを使う経路を限定し、必ずアプリケーション側で user_id フィルタリングを併用しています。
3. パフォーマンス最適化
- 並列クエリ: Promise.all で受講情報・通知・コンテンツデータをまとめて取得し、ダッシュボードの初期表示を高速化
- ISR (Incremental Static Regeneration): ナレッジ記事を60秒キャッシュ、microCMSのWebhookで即時再生成
- 画像最適化: アップロード時にブラウザ側で1MB / 1920pxに自動圧縮 → Supabase Storage に保存。next/imageで配信時の最適化も併用
- D&D 並び替え: ドラッグ&ドロップで
sort_orderを更新、楽観的UI反映+バックグラウンド保存
4. 自動運用機構
- Vercel Cron + Supabase RPC で毎日深夜にお知らせデータの自動クリーンアップ:
- 既読+90日経過したお知らせを削除
- 1ユーザーあたり未読50件超のものを古い順に削除
- ストレージのコスト・パフォーマンス両面で運用後の肥大化を防止
5. ヘッドレス CMS によるコンテンツ運用分離
ナレッジ(コラム)記事はmicroCMSで管理しています。非エンジニアのクライアントが記事追加・更新を即座に行えるようにすることで、コード変更を伴うコンテンツ運用を排除しました。
リッチテキストHTMLは isomorphic-dompurify でサニタイズしてから表示しています。
6. 認証ユーザーと業務ユーザーの紐付け
別サイト(受講申込フォーム)の本名と、Google認証で取得されるアカウント名が必ずしも一致しないという業務課題に対応しました。
- admin_name(管理名): 管理者が編集、申込者と紐付ける用途
- display_name(表示名): ユーザー自身が編集、投稿等で利用
UIコンテキストに応じて適切な名前を表示する設計としています。
UI/UXデザイン
Figmaを使ってデザインを 1 人で作成しました。クライアントの世界観(手芸 × 落ち着いた女性向け)に合わせた配色とフォントを採用しています。
- カラースキーム: ピンク
#d69eaf× ブラウン#6c5c56× ベージュ - フォント: Noto Sans JP(本文)× Shippori Mincho(見出し)
- レスポンシブ: モバイル / タブレット / PC に最適化、サイドバーとドロワーで自然な切り替え
- アクセシビリティ: 期限警告は色だけでなくテキストでも明示(赤色のみに依存しない)
主な機能
生徒向け
- ダッシュボード(受講中レッスン・未読お知らせ)
- コース/レッスン一覧・詳細
- Vimeo動画視聴(レスポンシブ対応)
- お知らせ一覧(既読管理・ページネーション)
- ナレッジ記事閲覧(カテゴリフィルタ・ページネーション)
- アカウント設定(表示名・プロフィール画像)
講師向け
- コース・レッスン CRUD
- ドラッグ&ドロップ並び替え
- 画像アップロード(D&D・自動圧縮)
- Vimeo URL 埋め込み
管理者向け
- ユーザー管理(一覧・検索・複合フィルタ・ロール変更)
- 受講管理(コース単位/レッスン単位の2階層期限管理)
- 複数選択での一括お知らせ送信・一括期限更新
- 期限切れ間近ユーザーのダッシュボード警告
設計上の工夫
コード品質
- TypeScript strict /
anyの使用を最小化 - ESLint + Prettier をプロジェクト全体で統一
- Server Components / Client Components の責務分離を明確化
- ピュアな状態管理(Server Actions 中心、グローバルストア無し)
ドキュメント
REQUIREMENTS.mdで要件・データ構造・権限設計を一元管理CLAUDE.mdでコーディング規約とプロジェクト固有ルールを明文化supabase/migrations/でDBスキーマ変更履歴を保持- 機能追加時はドキュメントと実装を同時更新するワークフローを徹底
開発フロー
developで機能開発、検証後mainにマージしてデプロイ(Vercel プレビューも併用)- コミット前に必ずローカルビルドを通す自己ルール
- ピュアヘルパー関数化を優先した設計でユニットテスト容易性を確保
今後の展開(実装予定)
フェーズ2、フェーズ3の開発としてクライアントと検討している機能です。
- 進捗管理: 講師フィードバック完了 → レッスン修了ステータス自動反映
- 作品アップロード + 講師フィードバック: 生徒が作品画像を投稿、講師がコメント
- 作品ギャラリー: 修了作品の公開展示機能
- 作品へのいいね: 公開されている生徒作品へ他の生徒がいいねをつけられる機能
- 進捗ベースのダッシュボード: 受講中レッスンを「未修了優先」でソート表示
個人としての成果
- 要件定義からクライアントの業務理解・課題抽出を主導
- UI/UXデザインをFigmaで実施、クライアントとの合意形成を担当
- 実装 はフロントエンド・バックエンド・DB・インフラ全領域を1人でカバー
- デプロイ・運用も継続中、機能追加等を担当
特に「2階層の閲覧期限管理」「アクセス制御ロジックの集約」など、ビジネス要件と技術設計を両側から考えて落とし所を作る経験を積めたプロジェクトとなりました。
- コメント
- 1年ほど生徒として通っていたディップアート教室で会員システムの相談を受け開発しました。 レッスン受講中のおしゃべりで経営者目線で事業の話や集客、SEOなどのWeb周りのアドバイスなどをしていたこともあり、「こういうシステムがほしい」「こういう機能があったらいいな」の要件だけ伺い、どうせ作るならもっと便利にしたい!という想いで様々な機能を提案させていただき、このシステムが出来上がりました。 リリースから3ヶ月が経ちましたが、致命的なバグの報告も受けておらず大変満足いただいております!
- タグ
- 会員サイト
- ログイン認証
- 動画配信
- 担当
- 要件定義
- デザイン
- API設計
- コーディング
- 運用
- ツール・技術
タップで名称を表示します

