Skip to content

REST APIエンドポイント設計

概要

Issue Outsource Platformの全REST APIエンドポイント仕様。 認証にはGitLab OAuthトークン(Bearer)を使用する。


共通仕様

ベースURL

https://<PF_DOMAIN>/api/v1

認証

認証方式ヘッダ形式説明
Bearer TokenAuthorization: Bearer <access_token>GitLab OAuth2で取得したアクセストークン
Webhook TokenX-Gitlab-Token: <secret>Webhook専用(内部用)

共通レスポンス形式

json
{
  "status": "success",
  "data": { ... },
  "meta": {
    "page": 1,
    "per_page": 20,
    "total": 100,
    "total_pages": 5
  }
}

エラーレスポンス形式

json
{
  "status": "error",
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid request parameters",
    "details": [
      { "field": "title", "message": "Title is required" }
    ]
  }
}

HTTPステータスコード

コード用途
200成功(取得・更新)
201成功(作成)
204成功(削除)
400リクエスト不正
401認証エラー
403権限不足
404リソース未存在
409競合(楽観ロック等)
422バリデーションエラー
429レートリミット超過
500内部サーバーエラー

ページネーション

全リスト系エンドポイントで共通のクエリパラメータを使用する。

パラメータデフォルト説明
pageint1ページ番号
per_pageint201ページあたり件数(最大100)
sortstringcreated_atソートフィールド
orderstringdescソート順(asc / desc

フィルタ

各エンドポイント固有のフィルタパラメータに加え、以下の共通フィルタを提供する。

パラメータ説明
searchstringキーワード検索(タイトル・説明)
created_afterdatetime作成日の下限
created_beforedatetime作成日の上限

ロール定義

ロール説明
adminプラットフォーム管理者
ownerプロジェクトオーナー(発注者)
engineer委託エンジニア(受注者)
reviewerレビュアー
public未認証ユーザー

エンドポイント一覧

認証 (/auth)

メソッドパス説明認証ロール
GET/auth/gitlabGitLab OAuth認証開始不要public
GET/auth/gitlab/callbackOAuthコールバック不要public
POST/auth/refreshトークンリフレッシュall
POST/auth/logoutログアウトall
GET/auth/me現在のユーザー情報all

プロジェクト (/projects)

メソッドパス説明認証ロール
GET/projectsプロジェクト一覧all
POST/projectsプロジェクト作成admin, owner
GET/projects/:idプロジェクト詳細all
PUT/projects/:idプロジェクト更新admin, owner
DELETE/projects/:idプロジェクト削除admin
POST/projects/:id/syncGitLabと手動同期admin, owner

Issue (/issues)

メソッドパス説明認証ロール
GET/projects/:project_id/issuesIssue一覧all
POST/projects/:project_id/issuesIssue作成admin, owner
GET/issues/:idIssue詳細all
PUT/issues/:idIssue更新admin, owner
DELETE/issues/:idIssue削除admin
POST/issues/:id/syncGitLabと手動同期admin, owner
GET/issues/:id/commentsIssueコメント一覧all
POST/issues/:id/commentsコメント追加all

アサイン (/assignments)

メソッドパス説明認証ロール
GET/issues/:issue_id/assignmentsアサイン一覧all
POST/issues/:issue_id/assignmentsアサイン申請engineer
PUT/assignments/:idアサイン承認・却下admin, owner
DELETE/assignments/:idアサイン取消admin, owner, engineer(自分)
GET/assignments/me自分のアサイン一覧engineer

レビュー (/reviews)

メソッドパス説明認証ロール
GET/issues/:issue_id/reviewsレビュー一覧all
GET/reviews/:idレビュー詳細all
PUT/reviews/:idレビュー結果登録admin, reviewer
GET/reviews/:id/commentsレビューコメント一覧all
POST/reviews/:id/commentsレビューコメント追加reviewer, engineer

報酬 (/rewards)

メソッドパス説明認証ロール
GET/rewards報酬一覧admin, owner
GET/rewards/me自分の報酬一覧engineer
GET/rewards/:id報酬詳細admin, owner, engineer(自分)
PUT/rewards/:id/status報酬ステータス更新admin
GET/rewards/summary報酬サマリーadmin, owner

ダッシュボード (/dashboard)

メソッドパス説明認証ロール
GET/dashboard/overview概要統計all
GET/dashboard/issues/statsIssue統計admin, owner
GET/dashboard/engineers/statsエンジニア統計admin, owner
GET/dashboard/rewards/stats報酬統計admin, owner
GET/dashboard/meマイダッシュボードengineer

Webhook (/webhooks)

メソッドパス説明認証ロール
POST/webhooks/gitlabGitLab Webhook受信Webhook Token-
GET/webhooks/eventsWebhookイベント履歴admin
GET/webhooks/events/:idイベント詳細admin
POST/webhooks/events/:id/retryイベント再処理admin

エンドポイント詳細

POST /auth/gitlab - GitLab OAuth認証開始

GitLab OAuthの認証URLへリダイレクトする。

レスポンス:

HTTP/1.1 302 Found
Location: https://gitlab.ethan-tech.jp/oauth/authorize?client_id=...&redirect_uri=...&response_type=code&scope=api+read_user

GET /auth/gitlab/callback - OAuthコールバック

クエリパラメータ:

パラメータ説明
codestring認証コード
statestringCSRF対策用state

レスポンス (200):

json
{
  "status": "success",
  "data": {
    "access_token": "pf_xxxxx",
    "refresh_token": "pf_ref_xxxxx",
    "expires_in": 3600,
    "user": {
      "id": "uuid",
      "gitlab_user_id": 14,
      "username": "take.otani",
      "display_name": "大谷剛弘",
      "avatar_url": "https://...",
      "role": "owner"
    }
  }
}

GET /auth/me - 現在のユーザー情報

レスポンス (200):

json
{
  "status": "success",
  "data": {
    "id": "uuid",
    "gitlab_user_id": 14,
    "username": "take.otani",
    "display_name": "大谷剛弘",
    "email": "take@example.com",
    "avatar_url": "https://...",
    "role": "owner",
    "created_at": "2026-01-01T00:00:00Z"
  }
}

POST /projects - プロジェクト作成

リクエスト:

json
{
  "name": "Issue Outsource PF",
  "description": "Issue駆動開発の業務委託プラットフォーム",
  "gitlab_project_id": 78,
  "gitlab_project_url": "https://gitlab.ethan-tech.jp/aieo/issueoutsourcing",
  "default_reward_currency": "JPY",
  "settings": {
    "auto_sync": true,
    "sync_labels": true,
    "sync_milestones": true,
    "reward_label_prefix": "reward:"
  }
}

レスポンス (201):

json
{
  "status": "success",
  "data": {
    "id": "uuid",
    "name": "Issue Outsource PF",
    "description": "Issue駆動開発の業務委託プラットフォーム",
    "gitlab_project_id": 78,
    "gitlab_project_url": "https://gitlab.ethan-tech.jp/aieo/issueoutsourcing",
    "status": "active",
    "settings": {
      "auto_sync": true,
      "sync_labels": true,
      "sync_milestones": true,
      "reward_label_prefix": "reward:"
    },
    "created_at": "2026-03-28T00:00:00Z",
    "updated_at": "2026-03-28T00:00:00Z"
  }
}

POST /projects/:project_id/issues - Issue作成

リクエスト:

json
{
  "title": "GitLab連携API設計",
  "description": "GitLab Webhook受信とREST APIの設計",
  "labels": ["api", "design"],
  "difficulty": "medium",
  "reward_amount": 10000,
  "reward_currency": "JPY",
  "milestone": "v1.0",
  "deadline": "2026-04-15T00:00:00Z",
  "sync_to_gitlab": true
}

レスポンス (201):

json
{
  "status": "success",
  "data": {
    "id": "uuid",
    "project_id": "uuid",
    "gitlab_issue_id": 649,
    "gitlab_issue_iid": 5,
    "title": "GitLab連携API設計",
    "description": "GitLab Webhook受信とREST APIの設計",
    "status": "open",
    "labels": ["api", "design"],
    "difficulty": "medium",
    "reward": {
      "amount": 10000,
      "currency": "JPY"
    },
    "milestone": "v1.0",
    "deadline": "2026-04-15T00:00:00Z",
    "assignee": null,
    "created_at": "2026-03-28T00:00:00Z",
    "updated_at": "2026-03-28T00:00:00Z",
    "gitlab_url": "https://gitlab.ethan-tech.jp/aieo/issueoutsourcing/-/issues/5"
  }
}

GET /projects/:project_id/issues - Issue一覧

フィルタパラメータ:

パラメータ説明
statusstringopen, assigned, in_review, completed, closed
labelsstringカンマ区切りのラベル
difficultystringeasy, medium, hard
assignee_iduuidアサインされたユーザーID
reward_minint報酬下限
reward_maxint報酬上限
has_rewardbool報酬付きのみ

レスポンス (200):

json
{
  "status": "success",
  "data": [
    {
      "id": "uuid",
      "title": "GitLab連携API設計",
      "status": "open",
      "labels": ["api", "design"],
      "difficulty": "medium",
      "reward": {
        "amount": 10000,
        "currency": "JPY"
      },
      "assignee": null,
      "created_at": "2026-03-28T00:00:00Z",
      "gitlab_url": "https://gitlab.ethan-tech.jp/aieo/issueoutsourcing/-/issues/5"
    }
  ],
  "meta": {
    "page": 1,
    "per_page": 20,
    "total": 12,
    "total_pages": 1
  }
}

POST /issues/:issue_id/assignments - アサイン申請

リクエスト:

json
{
  "message": "Claude Codeを使って対応します。2日以内に完了見込みです。",
  "estimated_hours": 8
}

レスポンス (201):

json
{
  "status": "success",
  "data": {
    "id": "uuid",
    "issue_id": "uuid",
    "engineer_id": "uuid",
    "status": "pending",
    "message": "Claude Codeを使って対応します。2日以内に完了見込みです。",
    "estimated_hours": 8,
    "created_at": "2026-03-28T00:00:00Z"
  }
}

PUT /assignments/:id - アサイン承認・却下

リクエスト:

json
{
  "status": "approved",
  "message": "承認します。ブランチを作成してください。"
}

レスポンス (200):

json
{
  "status": "success",
  "data": {
    "id": "uuid",
    "issue_id": "uuid",
    "engineer_id": "uuid",
    "status": "approved",
    "approved_at": "2026-03-28T01:00:00Z",
    "gitlab_assignee_synced": true
  }
}

GET /reviews/:id - レビュー詳細

レスポンス (200):

json
{
  "status": "success",
  "data": {
    "id": "uuid",
    "issue_id": "uuid",
    "gitlab_mr_id": 200,
    "gitlab_mr_iid": 10,
    "title": "feat: Issue #5 GitLab連携API実装",
    "status": "pending",
    "source_branch": "feature/issue-5",
    "target_branch": "main",
    "pipeline_status": "success",
    "comments_count": 3,
    "created_at": "2026-03-28T00:00:00Z",
    "gitlab_url": "https://gitlab.ethan-tech.jp/aieo/issueoutsourcing/-/merge_requests/10"
  }
}

PUT /reviews/:id - レビュー結果登録

リクエスト:

json
{
  "status": "approved",
  "comment": "LGTM。マージします。"
}

レスポンス (200):

json
{
  "status": "success",
  "data": {
    "id": "uuid",
    "status": "approved",
    "reviewed_at": "2026-03-28T02:00:00Z",
    "reviewer_id": "uuid",
    "reward_triggered": true
  }
}

GET /rewards/me - 自分の報酬一覧

フィルタパラメータ:

パラメータ説明
statusstringconfirmed, processing, paid, cancelled
period_startdate期間開始日
period_enddate期間終了日

レスポンス (200):

json
{
  "status": "success",
  "data": [
    {
      "id": "uuid",
      "issue_id": "uuid",
      "issue_title": "GitLab連携API設計",
      "amount": 10000,
      "currency": "JPY",
      "status": "confirmed",
      "confirmed_at": "2026-03-28T03:00:00Z",
      "paid_at": null
    }
  ],
  "meta": {
    "page": 1,
    "per_page": 20,
    "total": 5,
    "total_pages": 1
  }
}

GET /dashboard/overview - 概要統計

レスポンス (200):

json
{
  "status": "success",
  "data": {
    "issues": {
      "total": 50,
      "open": 20,
      "assigned": 15,
      "in_review": 8,
      "completed": 7
    },
    "engineers": {
      "total": 30,
      "active": 12
    },
    "rewards": {
      "total_amount": 500000,
      "currency": "JPY",
      "pending_amount": 100000,
      "paid_amount": 400000
    }
  }
}

GET /dashboard/me - マイダッシュボード

レスポンス (200):

json
{
  "status": "success",
  "data": {
    "active_assignments": [
      {
        "issue_id": "uuid",
        "issue_title": "GitLab連携API設計",
        "status": "in_progress",
        "deadline": "2026-04-15T00:00:00Z",
        "reward_amount": 10000
      }
    ],
    "pending_reviews": [
      {
        "review_id": "uuid",
        "mr_title": "feat: Issue #5 GitLab連携API実装",
        "status": "pending"
      }
    ],
    "reward_summary": {
      "total_earned": 150000,
      "pending_payment": 30000,
      "currency": "JPY"
    },
    "recent_activity": [
      {
        "type": "assignment_approved",
        "message": "Issue #5 のアサインが承認されました",
        "created_at": "2026-03-28T01:00:00Z"
      }
    ]
  }
}

レートリミット

対象制限ウィンドウ
認証済みユーザー1000リクエスト1時間
未認証60リクエスト1時間
Webhook制限なし(署名検証で制御)-

レートリミット超過時:

HTTP/1.1 429 Too Many Requests
Retry-After: 3600
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1711584000