アサインルール
概要
エンジニアが Issue を取得(アサイン)する際のルールを定義する。公平性・品質維持・進捗管理の観点から、同時着手数の制限、期限管理、競合制御を設ける。
同時着手数の制限
| 項目 | 値 | 備考 |
|---|---|---|
| 1人あたり最大同時着手数 | 3件 | In Progress + In Review + Changes Requested の合計 |
| 引き上げ条件 | 実績に応じてマネージャーが調整可 | 完了率・品質スコアを考慮 |
カウント対象のステート
以下のステートにある Issue がカウント対象:
- In Progress - 作業中
- In Review - レビュー待ち
- Changes Requested - 修正対応中
Approved 以降はカウント対象外(エンジニアの作業は実質完了のため)。
期限設定
デフォルト期限の算出
デフォルト期限 = アサイン取得日時 + (見積工数 × 1.5)| 見積工数 | デフォルト期限 |
|---|---|
| 2時間 | 3時間 |
| 1日(8時間) | 1.5日(12時間) |
| 3日(24時間) | 4.5日(36時間) |
| 1週間(40時間) | 1.5週間(60時間) |
期限の計算ルール
- 見積工数は 営業時間ベース(1日 = 8時間)で設定
- デフォルト期限は カレンダー時間(24時間ベース)で計算
- 土日・祝日は期限計算に含める(リモート・非同期前提のため)
- エンジニアは着手前に期限を確認し、困難な場合はアサイン取得前にマネージャーに相談
期限延長
| 項目 | 値 |
|---|---|
| 延長申請 | エンジニアがマネージャーに申請 |
| 最大延長回数 | 2回 |
| 1回あたり最大延長幅 | 元の見積工数の 50% |
| 申請期限 | デフォルト期限の 24時間前まで |
期限超過時の自動リリースルール
In Progress ステートでの超過
mermaid
flowchart TD
A[期限超過検知] --> B[エンジニアに警告通知]
B --> C{24時間以内に延長申請?}
C -->|Yes| D[マネージャーが判断]
D -->|承認| E[期限延長]
D -->|却下| F[自動リリース実行]
C -->|No| F
F --> G[ステートを Available に変更]
G --> H[アサイン解除]
H --> I[エンジニアに通知]
I --> J[作業ブランチは保持]- 期限超過時、エンジニアに警告通知を送信
- 24時間の猶予期間(Grace Period)を設ける
- 猶予期間内に延長申請がない場合、自動リリース
- 自動リリース時:
- Issue のステートを Available に変更
- エンジニアのアサインを解除
- 作業ブランチ・WIP MR は保持(引き継ぎ可能)
- エンジニアの実績に「期限超過」を記録
Changes Requested ステートでの超過
- 修正期限: 72時間(レビュー修正依頼から起算)
- 超過時は In Progress と同様の自動リリースフローを実行
- 猶予期間は 12時間(修正は比較的小規模のため短縮)
Issue 取得(アサイン)の競合制御
楽観的ロック方式
複数のエンジニアが同時に同じ Issue を取得しようとした場合の競合を、楽観的ロックで制御する。
mermaid
sequenceDiagram
participant E1 as エンジニアA
participant E2 as エンジニアB
participant API as APIサーバー
participant DB as データベース
E1->>API: Issue取得リクエスト (version: 1)
E2->>API: Issue取得リクエスト (version: 1)
API->>DB: UPDATE issues SET assignee=A, version=2 WHERE id=X AND version=1
DB-->>API: 成功 (1行更新)
API-->>E1: 取得成功
API->>DB: UPDATE issues SET assignee=B, version=2 WHERE id=X AND version=1
DB-->>API: 失敗 (0行更新 - version不一致)
API-->>E2: 取得失敗 (既に他のエンジニアが取得済み)実装方針
sql
-- Issue取得の競合制御(楽観的ロック)
UPDATE issues
SET
assignee_id = :engineer_id,
state = 'in_progress',
assigned_at = NOW(),
deadline = NOW() + (estimated_hours * 1.5 * INTERVAL '1 hour'),
version = version + 1
WHERE
id = :issue_id
AND state = 'available'
AND version = :expected_version;
-- 更新行数が0の場合 → 競合発生、リトライまたはエラー返却競合時のユーザー体験
- Issue 一覧画面では Available の Issue をリアルタイムで表示
- 取得ボタン押下時に楽観的ロックで排他制御
- 競合で失敗した場合、「この Issue は他のエンジニアが取得しました」と即時通知
- 画面を自動リフレッシュして最新の Available Issue 一覧を表示
アサイン解除条件
以下の条件でアサインが解除される:
| # | 条件 | トリガー | 解除後のステート |
|---|---|---|---|
| 1 | エンジニアの自主リリース | エンジニアが手動で解除 | Available |
| 2 | 期限超過(自動) | システムが自動検知 | Available |
| 3 | 修正期限超過(自動) | Changes Requested から 72時間超過 | Available |
| 4 | マネージャーによる強制解除 | マネージャーが手動で解除 | Available |
| 5 | Issue キャンセル | マネージャーが Issue をキャンセル | Cancelled |
アサイン解除時の処理
- Issue のアサイン情報をクリア
- Issue のステートを遷移
- 作業ブランチ・WIP MR は削除しない(引き継ぎ考慮)
- 解除理由を監査ログに記録
- 関係者(エンジニア・マネージャー)に通知
エンジニアの実績管理
アサインルールに関連するエンジニアの実績を記録し、将来的な同時着手数の調整に活用する。
| 指標 | 説明 |
|---|---|
| 完了数 | Done に到達した Issue 数 |
| 期限内完了率 | デフォルト期限内に In Review に到達した割合 |
| 期限超過数 | 自動リリースされた回数 |
| 自主リリース数 | エンジニアが途中で離脱した回数 |
| 平均レビュー修正回数 | Changes Requested の平均発生回数 |