# Matching Pro

## Setup

1. Copy `.env.example` to `.env` and adjust values if necessary. `VITE_API_BASE_URL` should point to the API server URL.
2. Run `node ace migration:run` and `node ace db:seed` to launch a MySQL container and load the schema and initial data.
   These scripts execute migrations, `server/make_initial_data_1.sql` and `server/make_initial_data_2.sql` in order.
   The host port for MySQL is read from the `DB_PORT` environment variable (default `3306`).
3. In another terminal start the API server with `npm run server`.
4. Start the frontend with `npm run dev`.

The API server listens on port 3333 and uses the `matching` MySQL database.
Registration now persists data in MySQL. When a company name is provided the
`companies` table is populated and the created `company_id` is stored on the new
user. The insert for both tables happens in a single transaction so partial
records are not left behind on error.

Available API endpoints now include profile, project search, profile search,
messages, interviews and contracts management.

## Build

### 全体ビルド

アプリケーション全体（AdonisJSバックエンド + Reactフロントエンド）をビルドします：

```bash
npm run build
```

このコマンドは以下を実行します：
- AdonisJSアプリケーションのビルド
- Reactフロントエンドのビルド（`/dist/`ディレクトリに出力）

### 個別ビルド

#### バックエンドのみビルド

```bash
npm run build:backend
```

#### フロントエンドのみビルド

```bash
npm run build:frontend
```

### ビルド出力

- **バックエンド**: AdonisJSの標準ビルド出力
- **フロントエンド**: `/dist/`ディレクトリに以下のファイルが生成されます：
  - `index.html` - メインHTMLファイル
  - `assets/` - JavaScript、CSS、その他の静的ファイル

### 本番環境での使用

ビルド後、以下の方法でアプリケーションを起動できます：

```bash
# ビルドされたアプリケーションを起動
npm start
```

### Skill data

Candidate profiles now store `experienced_skills` and `desired_skills` along with
`location` and desired `duration`. Projects keep `required_skills` and
`preferred_skills`.  A new `skills` table manages fine grained skill tags.
Each skill has `category_large` and `category_medium` columns to allow
grouped selection in the UI.

The utility `calculateAdvancedMatchScore` in `src/lib/utils.ts` computes match
scores considering skills, location, duration and budget with configurable
weights.

## マッチング計算方法

### スキル適合度の計算

スキル適合度は以下の方法で計算されます：

1. **必須スキルとの一致**
   - 同じスキルを持っている場合: **4点**
   - 同一グループのスキルを持っている場合: **2点**

2. **任意スキルとの一致**
   - 同じスキルを持っている場合: **2点**
   - 同一グループのスキルを持っている場合: **1点**

3. **満点の計算**
   - 必須スキル数 × 4点 + 任意スキル数 × 4点 = 満点

4. **適合度の算出**
   - 獲得点数 ÷ 満点 × 100 = スキル適合度（%）

### 経験適合度の計算

経験適合度は以下の方法で計算されます：

1. **必須スキルの経験年数評価**
   - 指定年数より長い経験年数: **4点**
   - 同じスキルで経験年数が1段階下: **2点**
   - それ未満: **1点**

2. **任意スキルの経験年数評価**
   - 指定年数より長い経験年数: **2点**
   - それ未満: **1点**

3. **満点の計算**
   - 必須スキル数 × 4点 + 任意スキル数 × 2点 = 満点

4. **適合度の算出**
   - 獲得点数 ÷ 満点 × 100 = 経験適合度（%）

### 稼働適合度の計算

稼働適合度は以下の方法で計算されます：

1. **開始日適合度**
   - 案件開始予定より前に開始可能: **3点**
   - 開始日より1ヶ月以内: **1点**

2. **稼働時間適合度**
   - 稼働可能時間が稼働時間以上: **3点**
   - 稼働時間-10時間以上: **1点**

3. **予算適合度**
   - 予算の上限・下限内: **4点**
   - 下限-20%〜上限+20%以内: **2点**

4. **勤務形態適合度**
   - 勤務形態が完全一致: **2点**
   - オンサイト/リモート案件でハイブリッド対応: **1点**

5. **満点の計算**
   - 開始日適合度: 3点 + 稼働時間適合度: 3点 + 予算適合度: 4点 + 勤務形態適合度: 2点 = **12点**

6. **適合度の算出**
   - 獲得点数 ÷ 12点 × 100 = 稼働適合度（%）

## バッチ処理

### マッチングバッチ処理

定期的にマッチングを実行するバッチ処理を提供しています。

#### 実行方法

**1. APIエンドポイント経由**

**Linux/macOSの場合:**
```bash
# 前回のバッチ実行時間以降を対象
curl -X POST http://localhost:3333/batch/matching

# 特定の開始日を指定
curl -X POST "http://localhost:3333/batch/matching?start_date=2024-01-01T00:00:00"
```

**Windows PowerShellの場合:**
```powershell
# 前回のバッチ実行時間以降を対象
Invoke-RestMethod -Uri "http://localhost:3333/batch/matching" -Method POST

# 特定の開始日を指定
Invoke-RestMethod -Uri "http://localhost:3333/batch/matching?start_date=2024-01-01T00:00:00" -Method POST

# または
curl.exe -X POST http://localhost:3333/batch/matching
curl.exe -X POST "http://localhost:3333/batch/matching?start_date=2024-01-01T00:00:00"
```

**2. コマンドライン経由**
```bash
cd api
npm run batch:matching
```

#### 処理内容

バッチ処理では以下の2つの処理を実行します：

1. **更新されたパートナーと既存案件のマッチング**
   - 指定された開始日以降に更新されたパートナーユーザー（プロフィール完成度70%以上）
   - 終了していない全ての案件（下書き・募集期間終了を除く）
   - 適合度50%以上でマッチングを作成または更新

2. **更新された案件と既存パートナーのマッチング**
   - 指定された開始日以降に更新された案件（下書き・募集期間終了を除く）
   - 全てのパートナーユーザー（プロフィール完成度70%以上）
   - 適合度50%以上でマッチングを作成または更新

#### 開始日の指定

- **start_dateパラメータ**: ISO形式（YYYY-MM-DDTHH:mm:ss）で開始日を指定
- **指定なし**: 前回のバッチ開始時間を使用
- **初回実行**: 前回のバッチ開始時間が記録されていない場合は1週間前から開始

### 対象外となる案件
- ステータスが「下書き」の案件
- 募集期間が終了している案件（end_dateが現在日付より前）

### 対象外となるパートナー
- プロフィール完成度が70%未満のユーザー

#### 実行結果

バッチ処理の実行結果には以下の情報が含まれます：

```json
{
  "success": true,
  "message": "マッチングバッチ処理が完了しました",
  "period": {
    "from": "2024-01-01T00:00:00.000Z",
    "to": "2024-01-02T00:00:00.000Z"
  },
  "results": {
    "newPartners": 5,
    "newProjects": 3,
    "activeProjects": 20,
    "totalPartners": 50,
    "partnerMatches": 15,
    "projectMatches": 8,
    "totalMatches": 23
  }
}
```

#### 定期実行の設定

cronを使用して定期実行する場合：

```bash
# 毎日午前2時に実行
0 2 * * * cd /path/to/api && npm run batch:matching

# 毎時間実行
0 * * * * cd /path/to/api && npm run batch:matching
```

## AdonisJS backend

A minimal AdonisJS application has been added under `backend/`. Models matching
`server/database-schema.sql` are defined in `backend/app/Models`. Example
controllers handle login, project creation and company updates. Start the
AdonisJS server with:

```bash
npm run adonis
```

This requires AdonisJS packages which are not installed in this environment.
An `IdleLogout` middleware now logs out users when their session has been idle for over five hours. It is registered globally in `backend/start/kernel.ts`.
