# 機能設計書 107-会員プロフィール編集

## 概要

本ドキュメントは、QuickerSite CMSにおけるログイン会員の自身のプロフィール編集機能について記載する。会員が自身のメールアドレス、パスワード、ニックネーム、カスタムフィールドを編集できる機能である。また、新規会員のアクティベーション後のプロフィール初期設定にも使用される。

### 本機能の処理概要

**業務上の目的・背景**：会員が自身の情報を管理・更新できるようにするために本機能が必要である。連絡先の変更、パスワードの変更、追加情報の登録など、会員自身で情報をメンテナンスできることで、管理者の負担を軽減し、情報の鮮度を保つことができる。

**機能の利用シーン**：ログイン済み会員がマイページからプロフィール編集を行う際に利用される。また、新規会員がアクティベーションリンクをクリックした後の初期プロフィール設定にも使用される。

**主要な処理内容**：
1. アクティベーションチケットの確認（新規会員の場合）
2. プロフィール編集フォームの表示
3. 入力値のバリデーション
4. 会員情報の保存
5. チケットの削除（新規会員の場合）
6. 新規会員登録通知メールの送信（設定時）
7. ウェルカムページへのリダイレクト（新規会員の場合）

**関連システム・外部連携**：会員情報データベース（tblContact, tblContactValues）との連携。チケット管理との連携。メール送信機能との連携（新規会員通知）。

**権限による制御**：ログイン済み会員またはアクティベーションチケット保持者のみアクセス可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 168 | プロフィール処理 | 主画面 | ログイン会員の自身のプロフィール編集 |

## 機能種別

データ更新処理 / フォーム処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| pageAction | String | Yes | アクション種別（"profile"） | 固定値チェック |
| ac | String | No | アクティベーションチケット | 新規会員の場合必須 |
| sEmail | String | Yes | メールアドレス | 必須、メール形式、最大50文字 |
| sPw | String | Yes | パスワード | 必須、最大20文字 |
| sNickName | String | Yes | ニックネーム | 必須、最大50文字 |
| bGetEmailsFromSite | Boolean | No | プライベートメッセージ受信許可 | true/false |
| btnaction | String | No | ボタンアクション（"save"） | 固定値チェック |
| カスタムフィールド | Mixed | No | 管理者定義のカスタムフィールド | フィールド設定による |
| QS_secCode | String | Yes | CSRFトークン | セッション値と比較 |

### 入力データソース

- POSTリクエスト: プロフィール編集フォームからの入力値
- QueryString: アクティベーションチケット（ac）
- Cookie: ログイン情報
- セッション: CSRFトークン

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| pageBody | String | プロフィール編集フォームHTML |
| pageTitle | String | プロフィール画面タイトル（customer.intranetMyProfile） |

### 出力先

画面表示（保存成功時はリダイレクトまたはメッセージ表示）

## 処理フロー

### 処理シーケンス

```
1. アクティベーションチケット確認
   └─ acパラメータがある場合、チケットを検索
   └─ 未ログインかつチケット無効の場合、リダイレクト

2. 初期値設定
   └─ チケット経由の場合、メールアドレスをチケットから取得

3. 保存処理（btnaction="save"の場合）
   └─ CSRF検証
   └─ フォーム値の取得
   └─ バリデーション
   └─ 会員情報保存
   └─ Cookie更新
   └─ チケット削除（新規の場合）
   └─ 管理者通知メール送信（設定時）
   └─ ウェルカムページリダイレクト（新規の場合）

4. フォーム生成
   └─ 基本情報フィールド（メール、パスワード、ニックネーム）
   └─ プライベートメッセージ設定
   └─ カスタムフィールド（bProfile=trueのもの）
   └─ アバターアップロードリンク（設定時）
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{チケットあり?}
    B -->|Yes| C[チケット検索]
    B -->|No| D{ログイン済み?}
    C --> E{チケット有効?}
    E -->|No| F[ログイン画面へ]
    E -->|Yes| G[メールアドレス設定]
    D -->|No| F
    D -->|Yes| H{保存ボタン?}
    G --> H
    H -->|Yes| I[CSRF検証]
    H -->|No| O[フォーム表示]
    I --> J[フォーム値取得]
    J --> K[バリデーション]
    K --> L{検証OK?}
    L -->|No| O
    L -->|Yes| M[会員情報保存]
    M --> N{新規会員?}
    N -->|Yes| P[チケット削除・通知]
    N -->|No| Q[成功メッセージ]
    P --> R[ウェルカムへ]
    Q --> O
    O --> S[フォームHTML生成]
    S --> T[終了]
    R --> T
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-701 | メール重複禁止 | 他会員と同一メールアドレス禁止（チケット経由の場合は許可） | 保存時 |
| BR-702 | ニックネーム重複禁止 | 他会員と同一ニックネーム禁止 | 保存時 |
| BR-703 | 必須フィールド | メール、パスワード、ニックネームは必須 | 保存時 |
| BR-704 | カスタムフィールド表示 | bProfile=trueのフィールドのみ表示 | フォーム生成時 |
| BR-705 | デフォルトステータス | 新規会員にはcustomer.iDefaultStatusを設定 | 新規保存時 |

### 計算ロジック

特になし

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 会員情報取得 | tblContact, tblContactValues | SELECT | 既存会員情報を取得 |
| 会員情報保存 | tblContact | INSERT/UPDATE | 会員基本情報を保存 |
| カスタムフィールド保存 | tblContactValues | DELETE/INSERT | カスタムフィールド値を保存 |
| 重複メール削除 | tblContact | DELETE | 重複メールの旧会員を削除 |
| チケット削除 | tblContactRegistration | DELETE | 使用済みチケットを削除 |

### テーブル別操作詳細

#### tblContact

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT/UPDATE | sEmail, sPw, sNickName, iStatus, dUpdatedTS, bGetEmailsFromSite | フォーム入力値 | 会員基本情報 |

#### tblContactValues

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| DELETE | - | iContactIDで削除 | 既存値をクリア |
| INSERT | iContactID, iFieldID, sValue | フォーム入力値 | カスタムフィールド値 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| err_mandatory | 必須エラー | 必須フィールド未入力 | エラーメッセージ表示 |
| err_email | メールエラー | メールアドレス形式不正 | エラーメッセージ表示 |
| err_doubleemail | 重複エラー | 他会員と同一メール | エラーメッセージ表示 |
| err_doublenickname | 重複エラー | 他会員と同一ニックネーム | エラーメッセージ表示 |
| err_wrongactivationlink | チケットエラー | 無効なアクティベーションリンク | エラーメッセージ表示 |

### リトライ仕様

エラー修正後に再送信可能。

## トランザクション仕様

会員情報保存、カスタムフィールド保存は個別のSQL文で実行（明示的なトランザクション制御なし）。

## パフォーマンス要件

単純な更新処理のため、特別な要件なし。

## セキュリティ考慮事項

- CSRF対策（QS_secCodeHidden、checkCSRF()）
- パスワード入力フィールドはtype="password"で表示をマスク
- encrypt関数によるフィールドIDの暗号化
- sanitize関数による出力エスケープ
- Cookieへのパスワード保存（暗号化）

## 備考

- イントラネット機能が有効（customer.intranetUse=true）かつマイプロフィール機能有効（customer.intranetUseMyProfile=true）の場合のみ動作
- アバター機能が有効（customer.bUseAvatars=true）の場合、アバターアップロードリンクを表示

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、会員情報を管理するクラス構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | contact.asp | `asp/includes/contact.asp` | cls_contactクラス、check/saveメソッド |
| 1-2 | ticket.asp | `asp/includes/ticket.asp` | cls_ticketクラス、アクティベーション管理 |

**読解のコツ**: cls_contact.save()メソッドがメインの保存処理。fieldsプロパティ（Dictionary）がカスタムフィールドを保持。

#### Step 2: エントリーポイントを理解する

処理の起点となるファイルを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | process.asp | `asp/process.asp` | pageAction="profile"時のinclude処理（140-142行目） |

**主要処理フロー**:
1. **140行目**: `case cProfile` - プロフィールアクションの分岐
2. **141行目**: `if customer.intranetUse and customer.intranetUseMyProfile then` - 機能有効チェック
3. **141行目**: `<!-- #include file="process_profile.asp"-->` - 処理インクルード

#### Step 3: プロフィール編集処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | process_profile.asp | `asp/process_profile.asp` | プロフィール編集のメインロジック |

**主要処理フロー**:
- **2-10行目**: チケット確認とリダイレクト制御
- **14行目**: カスタムフィールド取得
- **15-46行目**: 保存処理（CSRF検証、バリデーション、保存、通知）
- **48-117行目**: フォームHTML生成

### プログラム呼び出し階層図

```
process.asp (エントリーポイント)
    │
    ├─ process_profile.asp (プロフィール編集処理)
    │      │
    │      ├─ cls_ticket.pickByTicket() (チケット確認)
    │      │
    │      ├─ checkCSRF() (CSRF検証)
    │      │
    │      ├─ logon.contact.getRequestValues() (値取得)
    │      │
    │      ├─ logon.contact.save() (保存)
    │      │    ├─ check() - バリデーション
    │      │    ├─ tblContact INSERT/UPDATE
    │      │    └─ tblContactValues 更新
    │      │
    │      └─ cls_mail_message.send() (新規会員通知)
    │
    └─ template (テンプレート処理)
```

### データフロー図

```
[入力]               [処理]                    [出力]

ac(チケット) ───▶ cls_ticket確認 ────▶ 認証状態
フォーム値 ────▶ getRequestValues() ──▶ cls_contact
       │                │                    │
       ▼                ▼                    ▼
QS_secCode ────▶ checkCSRF() ────────▶ 検証結果
       │                │
       ▼                ▼
tblContact ◀───── save() ──────────▶ 保存結果
tblContactValues          │
                          ▼
                   チケット削除
                   通知メール
                   リダイレクト
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| process_profile.asp | `asp/process_profile.asp` | ソース | プロフィール編集処理メイン |
| process.asp | `asp/process.asp` | ソース | ページアクションルーター |
| contact.asp | `asp/includes/contact.asp` | ソース | 会員クラス定義 |
| contactField.asp | `asp/includes/contactField.asp` | ソース | カスタムフィールドクラス |
| ticket.asp | `asp/includes/ticket.asp` | ソース | チケットクラス定義 |
| LogonEdit.asp | `asp/includes/LogonEdit.asp` | ソース | logonクラス定義 |
| mail_message.asp | `asp/includes/mail_message.asp` | ソース | メール送信クラス |
| customer.asp | `asp/includes/customer.asp` | ソース | 顧客設定クラス |
