# sports-quiz

スポーツクイズ向け Web アプリケーション（Laravel 11）です。管理画面・チーム画面・ゲスト画面の 3 系統で利用します。

## 動作環境

| 項目 | バージョン |
|------|------------|
| PHP | 8.2 以上 |
| Composer | 2.x |
| Node.js | 18 以上（フロント資産ビルド用） |
| MySQL | 8.x 推奨 |

### 推奨 PHP 拡張

- `bcmath`, `ctype`, `curl`, `dom`, `fileinfo`, `json`, `mbstring`, `openssl`, `pdo`, `pdo_mysql`, `tokenizer`, `xml`, `zip`
- 画像アップロード・PDF 生成: `gd` または `imagick`

## セットアップ手順

### 1. 依存パッケージのインストール

```bash
composer install
npm install
```

### 2. 環境変数の設定

```bash
cp .env.example .env
php artisan key:generate
```

`.env` を編集し、少なくとも次の項目を環境に合わせて設定してください。

| 変数 | 説明 |
|------|------|
| `APP_URL` | アクセス URL（例: `http://127.0.0.1:8000`）。画像 URL の生成にも使用されます。 |
| `APP_TIMEZONE` | タイムゾーン（例: `Asia/Tokyo`） |
| `APP_LOCALE` / `APP_FALLBACK_LOCALE` | ロケール（例: `ja`） |
| `DB_*` | MySQL 接続情報 |
| `MAIL_*` | メール送信（パスワードリセット等） |
| `SESSION_DRIVER` | `database` 推奨（マイグレーションで `sessions` テーブルが必要） |
| `SESSION_COOKIE_ADMIN` / `SESSION_COOKIE_TEAM` / `SESSION_COOKIE_GUEST` | 管理・チーム・ゲストでセッションを分離 |
| `FIXED_TEAM` | チーム固定モード（`true` / `false`） |
| `DEFAULT_TEAM` | デフォルトチームコード（`teams.code`）。指定するとチームトップ `/team` でチーム名入力画面を表示せず、`/team/teams/{code}` へ自動リダイレクト |
| `AWS_*` | S3 経由のファイルアップロード機能を使う場合 |

### 3. データベースの準備

```bash
# MySQL にデータベースを作成したうえで
php artisan migrate
php artisan db:seed   # 初期データが必要な場合
```

### 4. ストレージのシンボリックリンク（必須）

本システムでは、ロゴやクイズ画像などを **Laravel の `public` ディスク** に保存します。

| 種別 | パス |
|------|------|
| 実ファイルの保存先 | `storage/app/public/img/` |
| DB に登録する URL | `/storage/img/ファイル名.jpg` |
| ブラウザからの公開 URL | `{APP_URL}/storage/img/ファイル名.jpg` |

ブラウザは `public/storage` 経由でファイルを参照するため、次のシンボリックリンクが **必須** です。

```bash
php artisan storage:link
```

実行後、次のリンクが作成されます。

```
public/storage  →  storage/app/public
```

#### 確認方法

```bash
# Windows（PowerShell）
Get-Item public\storage | Select-Object LinkType, Target

# Linux / macOS
ls -la public/storage
```

リンク作成後、次の URL で画像が表示されれば成功です。

```
{APP_URL}/storage/img/（アップロードしたファイル名）
```

#### 画像が表示されない場合

1. `php artisan storage:link` を実行しているか確認する
2. `storage/app/public/img/` にファイルが存在するか確認する
3. `APP_URL` が実際のアクセス URL と一致しているか確認する
4. Web サーバーのドキュメントルートが `public/` になっているか確認する

> **補足:** `storage/app/public/` 直下にファイルだけがあり `img/` 配下にない場合、DB のパスと実体がずれて表示されません。再アップロードするか、ファイルを `storage/app/public/img/` に移動してください。

### 5. ディレクトリの権限

Web サーバーから書き込み可能にしてください。

```bash
# Linux / macOS の例
chmod -R 775 storage bootstrap/cache
```

### 6. フロント資産のビルド

```bash
# 本番・検証環境
npm run build

# 開発時（ホットリロード）
npm run dev
```

## アプリケーションの起動

### 開発用（簡易）

```bash
php artisan serve
```

ブラウザで `http://127.0.0.1:8000` にアクセスします（`APP_URL` と合わせてください）。

### 開発用（サーバー + キュー + Vite 同時起動）

```bash
composer dev
```

メールはキュー経由で送信されるため、本番に近い動作確認時はキューワーカーも起動してください。

```bash
php artisan queue:work
```

## URL 構成

| プレフィックス | 用途 |
|----------------|------|
| `/admin` | 管理画面 |
| `/team` | チーム会員画面 |
| `/guest` | ゲスト画面 |

ルート `/` は `/guest/login` へリダイレクトされます。

## ファイルアップロードについて

### ローカル保存（チームロゴ・クイズ画像など）

- アップロード処理: `App\Models\File::makeUploadedRecord()`
- 保存先: `storage/app/public/img/`
- 表示: `File::publicUrl()` または Blade から `\App\Models\File::publicUrl($path)`

**`php artisan storage:link` 未実行のままでは画像は表示されません。**

### S3 保存（一部のファイル API）

チーム・管理のファイル API で S3 を利用する場合は、`.env` の `AWS_*` を設定し、必要に応じて `config/aws_s3.php` 等の S3 パス設定を行ってください。

## 本番環境での追加設定

- Web サーバー（Apache / Nginx）のドキュメントルートを **`public/`** に設定する
- `APP_ENV=production`, `APP_DEBUG=false` にする
- `php artisan config:cache`, `php artisan route:cache`, `php artisan view:cache` を検討する
- デプロイ後に `php artisan migrate --force` と **`php artisan storage:link`** を実行する
- PDF 出力（表彰状等）では dompdf 用フォント（Noto Sans JP）を使用します。フォントファイルは `vendor/dompdf/dompdf/lib/fonts/` を参照します

## よく使う Artisan コマンド

```bash
php artisan migrate          # マイグレーション
php artisan db:seed          # シーダー
php artisan storage:link     # 公開ストレージのシンボリックリンク作成
php artisan queue:work       # キューワーカー
php artisan config:clear     # 設定キャッシュクリア
```

## トラブルシューティング

| 症状 | 確認・対処 |
|------|------------|
| アップロードした画像が表示されない | `php artisan storage:link` を実行する。`public/storage` が `storage/app/public` を指しているか確認する |
| DB の URL と実ファイルの場所が違う | DB: `/storage/img/xxx.jpg`、実体: `storage/app/public/img/xxx.jpg` であることを確認する |
| セッションが維持されない | `SESSION_DRIVER=database` の場合、`sessions` テーブルが存在するか確認する |
| メールが届かない | `MAIL_*` の設定、`php artisan queue:work` の起動を確認する |
| 500 エラー（設定変更後） | `php artisan config:clear` を実行する |
