体験入店 - イケメン投票システム

体験入店 - イケメン投票システム

プロジェクト概要

「体験入店」は、地雷系テーマの美しいデザインを特徴とするイケメン投票システムです。既存のAI Host Clubシステムの追加機能として開発され、モダンなWeb技術を駆使してユーザビリティと保守性を両立させたプロジェクトです。

🎯 開発コンセプト

「シンプル × 高機能 × 安定動作」

  • 地雷系 × ゴシック × 可愛いのデザインテーマ
  • 脱JavaScript依存によるモダンなサーバーサイド駆動開発
  • Progressive Enhancementによる段階的機能拡張
  • データ保護最優先の安全な機能追加

🌟 主要機能

ユーザー向け機能

  • 直感的な投票システム: ハートマークをクリックするだけの簡単操作
  • 視覚的フィードバック: 1票→小さなハート💕、10票→大きなハート💖への変換
  • 全画面画像表示: 候補者画像クリックでモーダル表示
  • リアルタイムランキング: 投票結果の即座反映

管理者向け機能

  • 複数管理者対応: 安全な管理者追加・削除システム
  • 写真確認機能: 削除前のサムネイル拡大表示
  • 統計ダッシュボード: システム全体の詳細分析
  • レスポンシブ管理画面: モバイル対応の管理UI

🛠️ 技術的な工夫

1. モダンなフロントエンド設計

脱JavaScript依存の革新的アプローチ

<!-- HTMX: サーバーサイド駆動型UI更新 -->
<img hx-get="/image_modal/filename.jpg" 
     hx-target="body" 
     hx-swap="beforeend">

<!-- Alpine.js: 軽量リアクティブフレームワーク -->
<div x-data="{showModal: true}" 
     x-show="showModal"
     @keydown.escape.window="closeModal()">

選択理由:
- JavaScriptの記述量を最小化
- 宣言的なUI定義
- サーバーサイドでのHTMLレンダリング
- 軽量で高性能な動作

2. 画像処理の最適化

固定領域切り出し方式の採用

def create_top_crop_image(original_path, crop_size=640):
    # 画像上部640x640を切り出し(中央寄せ)
    x_offset = max(0, (img_width - crop_size) // 2)
    cropped = image[0:crop_size, x_offset:x_offset+crop_size]
    return cv2.resize(cropped, target_size, interpolation=cv2.INTER_LANCZOS4)

技術的メリット:
- 100%確実な画像表示(AI顔検出の不安定性を回避)
- 高速処理(50ms未満)
- シンプルなコード構造(保守性向上)

3. レスポンシブ設計の徹底

CSS clamp()による動的フォントサイズ

.logo {
    font-size: clamp(1.4rem, 4vw, 1.8rem);
    white-space: nowrap;
    word-break: keep-all;
    letter-spacing: -0.02em;
}

効果:
- 画面幅に応じた自動調整
- 意図しない改行の防止
- 日本語に適した改行制御

4. 安全なデータベース設計

非破壊的機能追加

# 既存テーブル構造を変更せずに機能拡張
def migrate_database():
    try:
        # 新しいカラムが存在するかチェック
        with db.engine.connect() as conn:
            conn.execute(text("SELECT email FROM admin LIMIT 1"))
    except Exception:
        # 必要に応じて安全にカラム追加
        conn.execute(text("ALTER TABLE admin ADD COLUMN email VARCHAR(120)"))

🎨 デザインの特徴

地雷系テーマの実装

  • ピンク×黒のゴシック配色
  • 浮遊ハート背景: 常時アニメーションエフェクト
  • バタフライエフェクト: 投票時の蝶アニメーション
  • グラデーション多用: 深みのある視覚表現

レイアウト最適化

  • コンパクト設計: 名前と票数の横並び配置
  • 余白最適化: 画面効率を50%向上
  • 段階的レスポンシブ: デスクトップ→タブレット→スマートフォンの最適化

📊 開発プロセス

バージョン管理戦略

  1. v1.0.0: 基本機能実装(Vanilla JavaScript)
  2. v2.0.0: 大規模リファクタリング(HTMX + Alpine.js移行)
  3. v2.1.x: 画像処理最適化(AI顔検出→固定切り出し)
  4. v2.2.x: UI/UX改善・管理機能強化

技術的課題と解決

課題1: AI顔検出の精度問題
- 問題: 検出率60-70%、処理時間200-500ms
- 解決: 固定領域切り出し方式で100%確実な表示

課題2: JavaScript保守性の課題
- 問題: 複雑なDOM操作、状態管理
- 解決: HTMX + Alpine.jsによる宣言的実装

課題3: モバイルでの表示崩れ
- 問題: 「体験入店」の意図しない改行
- 解決: CSS clamp()とword-break制御

🔒 セキュリティ対策

多層防御の実装

  • 管理者認証: Flask-Loginによる認証システム
  • 入力バリデーション: フロントエンド+バックエンド二重チェック
  • SQLインジェクション対策: SQLAlchemy ORMによる保護
  • ファイルアップロード制限: MIMEタイプ・サイズ制限

管理者管理の安全機能

  • 重複防止: ユーザー名の重複チェック
  • パスワード強度: 最低6文字の強制
  • 安全装置: 最後の管理者削除防止・自己削除防止

📱 レスポンシブ対応

ブレークポイント戦略

/* デスクトップ優先設計 */
@media (max-width: 768px) { /* タブレット */ }
@media (max-width: 480px) { /* スマートフォン */ }
@media (max-width: 320px) { /* 極小画面 */ }

/* タッチデバイス対応 */
@media (hover: none) and (pointer: coarse) {
    .clickable-image:hover { transform: none; }
    .clickable-image:active { transform: scale(1.05); }
}

🚀 パフォーマンス最適化

最適化手法

  1. 画像最適化: 動的リサイズ・品質調整
  2. キャッシュ戦略: ブラウザキャッシュの活用
  3. 部分更新: HTMXによるAjax不要の動的コンテンツ
  4. CSS最適化: ハードウェアアクセラレーション対応

実測値

  • 画像処理: 50ms未満(従来比90%削減)
  • ページ読み込み: HTMX部分更新で大幅高速化
  • レスポンシブ対応: 280px〜1200px+まで破綻なし

🔧 開発環境・技術スタック

バックエンド

  • Flask: Webアプリケーションフレームワーク
  • SQLAlchemy: データベースORM
  • SQLite: 軽量データベース
  • OpenCV: 画像処理エンジン

フロントエンド

  • HTMX: サーバーサイド駆動型UI
  • Alpine.js: 軽量リアクティブフレームワーク
  • CSS Grid/Flexbox: モダンレイアウト
  • CSS Transitions: 滑らかなアニメーション

開発ツール

  • Python 3.7+: 開発言語
  • Git: バージョン管理
  • 環境変数管理: .envファイル活用

📈 成果・学び

技術的成果

  • 保守性向上: JavaScript削減により可読性・保守性が大幅改善
  • パフォーマンス向上: 画像処理最適化で90%の処理時間削減
  • UI統一: コンポーネント化による一貫したユーザー体験
  • 安全性向上: 非破壊的機能追加による既存データ完全保護

学習ポイント

  1. モダンWeb技術: HTMX + Alpine.jsによる脱JavaScript開発
  2. 画像処理: OpenCVを活用した実用的な画像最適化
  3. レスポンシブ設計: CSS新機能を活用した効率的な実装
  4. 段階的改善: 既存システムを破壊せずに機能追加する手法

🎯 今後の展開

機能拡張計画

  • 投票制限機能: IPベース・時間ベースの制限
  • カテゴリ機能: 候補者のグループ分け
  • SNS連携: ソーシャルログイン・シェア機能
  • 権限管理: 管理者権限レベルの細分化

技術的改善

  • PWA対応: Service Worker実装
  • リアルタイム通信: WebSocket導入
  • 国際化対応: 多言語サポート
  • アクセシビリティ: WCAG 2.1 AA準拠

💡 プロジェクトから得られた知見

このプロジェクトを通じて、「技術選択の重要性」「段階的改善の価値」を実感しました。特に、AI顔検出から固定切り出しへの方針転換では、確実性と保守性を重視する判断の重要性を学びました。

また、HTMX + Alpine.jsによる「脱JavaScript依存」のアプローチは、従来のSPA開発とは異なる新しい可能性を示し、シンプルで保守しやすいWebアプリケーションの実現に大きく貢献しました。


🎉 素敵な投票システムライフをお楽しみください! 🦋✞

同様の開発をご希望ですか?

この事例と同様の開発やカスタマイズについて、
お気軽にご相談ください。

お問い合わせ