← 成果物一覧に戻る

API設計書

Version 1.0.0 | SB-Ticket(シュートボクシング)

SB-Ticket API リファレンス

Version: 0.1.0 Base URL: https://sb-ticket.com (本番) / http://localhost:8000 (ローカル) 認証方式: JWT (HttpOnly Cookie) ドキュメントURL: /docs (Swagger UI) / /redoc (ReDoc)


目次


エンドポイント一覧

#メソッドパス説明認証
1GET/healthヘルスチェック不要
認証
2POST/api/auth/loginログイン不要
3POST/api/auth/logoutログアウト不要
4POST/api/auth/refreshトークンリフレッシュCookie
5POST/api/auth/password-changeパスワード変更必要
6POST/api/auth/sms-sendSMS認証コード送信不要
7POST/api/auth/sms-verifySMS認証コード検証不要
8POST/api/auth/phone-register電話番号登録必要
イベント
9GET/api/events/イベント一覧必要
10GET/api/events/{event_id}イベント詳細必要
11POST/api/events/イベント作成Admin
12PUT/api/events/{event_id}イベント更新Admin
13DELETE/api/events/{event_id}イベント削除Admin
14GET/api/events/{event_id}/playersイベント参加選手一覧必要
15POST/api/events/{event_id}/players選手をイベントにアサインAdmin
16PUT/api/events/{event_id}/players/{player_id}ノルマ更新Admin
17GET/api/events/{event_id}/sales-stats販売統計必要
チケット
18GET/api/tickets/チケット一覧必要
19GET/api/tickets/{ticket_id}チケット詳細必要
20POST/api/tickets/manual-sale手動チケット販売登録必要
21PUT/api/tickets/{ticket_id}チケット更新必要
22DELETE/api/tickets/{ticket_id}チケット削除必要
23POST/api/tickets/webhook/piaチケットぴあ Webhook署名検証
選手
24GET/api/players/選手一覧Admin/Association
25GET/api/players/me自分のプロフィール必要
26PUT/api/players/meプロフィール更新必要
27POST/api/players/me/imageプロフィール画像アップロード必要
28GET/api/players/public/{slug}公開プロフィール不要
29GET/api/players/{player_id}選手詳細必要
30GET/api/players/{player_id}/qr/{event_id}QRコード生成必要
31POST/api/players/選手作成Admin
32PUT/api/players/{player_id}選手更新Admin
33DELETE/api/players/{player_id}選手削除(論理)Admin
LP
34GET/api/lps/LP一覧必要
35GET/api/lps/{lp_id}LP詳細必要
36POST/api/lps/generate/{event_id}LP生成 (Claude AI)Admin
37POST/api/lps/generateLP生成 (リクエストボディ)必要
38PUT/api/lps/{lp_id}LP更新Admin
39POST/api/lps/{lp_id}/publishLP公開Admin
40POST/api/lps/{lp_id}/unpublishLP非公開Admin
41GET/api/lps/{lp_id}/previewLPプレビュー (HTML)必要
ファン
42GET/api/fans/ファン一覧必要
43GET/api/fans/dig-out掘り起こしリスト必要
44GET/api/fans/{fan_id}ファン詳細必要
45GET/api/fans/{fan_id}/purchasesファン購入履歴必要
46POST/api/fans/ファン作成必要
47PUT/api/fans/{fan_id}ファン更新必要
48DELETE/api/fans/{fan_id}ファン削除必要
スポンサー
49GET/api/sponsors/スポンサー一覧必要
50GET/api/sponsors/{sponsor_id}スポンサー詳細必要
51POST/api/sponsors/スポンサー作成Admin
52PUT/api/sponsors/{sponsor_id}スポンサー更新Admin
53DELETE/api/sponsors/{sponsor_id}スポンサー論理削除Admin
54PUT/api/sponsors/{sponsor_id}/concept-statusコンセプトステータス更新Admin/Association
55POST/api/sponsors/{sponsor_id}/publish協会公開トグルAdmin/Association
56POST/api/sponsors/{sponsor_id}/approve公開承認Admin
キックバック
57GET/api/kickbacks/キックバック一覧Admin/Association
58GET/api/kickbacks/{kickback_id}キックバック詳細Admin/Association
59POST/api/kickbacks/キックバック作成Admin/Association
60PUT/api/kickbacks/{kickback_id}キックバック更新Admin/Association
61POST/api/kickbacks/{kickback_id}/mark-paid支払済マークAdmin/Association
62GET/api/kickbacks/summaryキックバックサマリーAdmin/Association
63GET/api/kickbacks/export-csvCSV エクスポートAdmin
通知
64GET/api/notifications/通知一覧必要
65GET/api/notifications/unread-count未読数必要
66POST/api/notifications/{notification_id}/read既読にする必要
67POST/api/notifications/read-all全て既読にする必要
68POST/api/notifications/send通知送信Admin
69POST/api/notifications/bulk-deadline締切アラート一斉送信Admin
ランキング
70GET/api/rankings/salesチケット販売ランキング必要
71GET/api/rankings/viewsページビューランキング必要
72GET/api/rankings/daily/{event_id}日別販売データ必要
73GET/api/rankings/daily前日販売ランキング必要
管理者
74GET/api/admin/dashboardダッシュボード統計Admin
75GET/api/admin/audit-logs監査ログAdmin
76GET/api/admin/players選手管理一覧Admin
77POST/api/admin/players選手アカウント作成Admin
78POST/api/admin/players/{player_id}/lockアカウントロックAdmin
79POST/api/admin/players/{player_id}/unlockアカウントアンロックAdmin
80POST/api/admin/players/{player_id}/reset-passwordパスワードリセットAdmin
営業パイプライン
81GET/api/concept/leadsリード一覧Association
82GET/api/concept/leads/pipeline-summaryパイプラインサマリーAssociation
83PUT/api/concept/leads/{sponsor_id}/advanceステージ進行Association
84PUT/api/concept/leads/{sponsor_id}/statusステータス設定Association
85POST/api/concept/leads/{sponsor_id}/publish協会公開トグルAssociation
86GET/api/concept/kickbacksキックバック一覧(営業)Association
87POST/api/concept/kickbacksキックバック作成(営業)Association
報酬
88GET/api/rewards/報酬一覧必要
89GET/api/rewards/my自分の収入サマリー必要
90POST/api/rewards/calculate/{event_id}報酬計算Admin
91POST/api/rewards/{reward_id}/mark-paid報酬支払済マークAdmin
92GET/api/rewards/summary報酬サマリーAdmin

合計: 92エンドポイント


認証・ロール

認証方式

JWTトークンをHttpOnly Cookieで管理する。ログイン成功時に access_tokenrefresh_token がCookieにセットされる。

Cookie名有効期限用途
access_token設定値 (デフォルト30分)API認証
refresh_token7日間トークン更新

ロール一覧

ロール説明
Playerplayer一般選手。自分のデータのみアクセス可
Adminadmin管理者。全データへのフルアクセス
Associationassociation協会/コンセプト管理者。営業パイプライン管理

認証レベル

レベル説明
不要認証なしでアクセス可能
必要有効なJWTトークンが必要
Adminadmin ロールが必要
Admin/Associationadmin または association ロールが必要
Associationassociation ロールが必要
署名検証HMAC-SHA256署名によるWebhook認証

Rate Limiting

CategoryLimitScope
Authentication endpoints10 requests/minPer IP
General API100 requests/minPer user
Webhook callbacks1000 requests/minPer endpoint
LP generation (Claude API)5 requests/minPer user

Rate limit headers:

Exceeding limits returns 429 Too Many Requests.


共通レスポンス

SuccessResponse

{
  "success": true,
  "message": "OK"
}

ErrorResponse

{
  "error": "string",
  "message": "Human-readable error message",
  "detail": "Additional error detail (optional)"
}

ページネーション

多くのリストエンドポイントは以下のクエリパラメータをサポート:

パラメータデフォルト説明
pageint1ページ番号 (1始まり)
per_pageint201ページあたりの件数 (最大100)

列挙型 (Enum)

PlayerRole

説明
player一般選手
admin管理者
association協会

EventStatus

説明
draft下書き
published公開中
closed終了
cancelledキャンセル

TicketRoute

説明
lpランディングページ経由
piaチケットぴあ経由
manual手動登録
otherその他

LPStatus

説明
draft下書き
published公開中
unpublished非公開

ConceptStatus

説明
leadリード
proposal提案中
negotiation交渉中
contracted契約済
declined辞退

NotificationType

説明
smsSMS通知
web_pushWebプッシュ通知
in_appアプリ内通知

1. Health Check

GET /health

ロードバランサー・監視用ヘルスチェック。

認証: 不要

レスポンス:

{
  "status": "ok",
  "service": "sb-ticket-api",
  "version": "0.1.0"
}

2. Authentication (認証)

POST /api/auth/login

選手ログイン。認証成功時にJWTトークンをHttpOnly Cookieにセット。

認証: 不要

リクエストボディ:

フィールド必須説明
login_idstringYesログインID
passwordstringYesパスワード (8文字以上)

レスポンス (TokenResponse):

フィールド説明
access_tokenstringJWTアクセストークン
token_typestring"bearer"
expires_inint有効期限 (秒)

備考:


POST /api/auth/logout

ログアウト。JWT Cookieを削除。

認証: 不要

レスポンス: SuccessResponse


POST /api/auth/refresh

リフレッシュトークンから新しいアクセストークンを発行。

認証: refresh_token Cookie

レスポンス: TokenResponse


POST /api/auth/password-change

認証済み選手のパスワード変更。

認証: 必要

リクエストボディ:

フィールド必須説明
current_passwordstringYes現在のパスワード (8文字以上)
new_passwordstringYes新しいパスワード (8文字以上)

レスポンス: SuccessResponse

備考: 新パスワードは現在・過去のパスワードと異なる必要がある。bcrypt (cost 12) でハッシュ化。


POST /api/auth/sms-send

SMS認証コード送信 (Twilio Verify)。

認証: 不要

リクエストボディ:

フィールド必須説明
phone_numberstringYesE.164形式の電話番号 (例: +819012345678)

レスポンス: SuccessResponse


POST /api/auth/sms-verify

SMS認証コードを検証しログイン完了。

認証: 不要

リクエストボディ:

フィールド必須説明
phone_numberstringYesE.164形式の電話番号
codestringYes6桁の認証コード

レスポンス: TokenResponse


POST /api/auth/phone-register

認証済み選手の電話番号登録。AES-256で暗号化して保存。

認証: 必要

リクエストボディ:

フィールド必須説明
phone_numberstringYesE.164形式の電話番号

レスポンス: SuccessResponse


3. Events (イベント)

GET /api/events/

イベント一覧取得。ステータスフィルタ・ページネーション対応。

認証: 必要

クエリパラメータ:

パラメータ必須デフォルト説明
statusstringNo-ステータスフィルタ
pageintNo1ページ番号
per_pageintNo20件数 (最大100)

レスポンス: EventResponse[]


GET /api/events/{event_id}

イベント詳細取得。

認証: 必要 パスパラメータ: event_id (UUID)

レスポンス (EventResponse):

フィールド説明
idstringイベントUUID
namestringイベント名
datedate開催日
venuestring会場名
door_timetime?開場時間
start_timetime?開始時間
sale_start_datedate?販売開始日
sale_deadlinedate?販売締切日
seat_typesSeatType[]席種と価格
sales_channelsstring[]販売チャネル
pia_base_urlstring?チケットぴあURL
promo_textstringプロモーションテキスト
statusEventStatusステータス
created_atdatetime作成日時

SeatType:

フィールド説明
namestring席種名 (例: S席, A席)
priceint価格 (JPY)

POST /api/events/

イベント作成。

認証: Admin 監査ログ: あり

リクエストボディ (EventCreate):

フィールド必須説明
namestringYesイベント名
datedateYes開催日
venuestringYes会場名
door_timetimeNo開場時間
start_timetimeNo開始時間
sale_start_datedateNo販売開始日
sale_deadlinedateNo販売締切日
seat_typesSeatType[]No席種リスト
sales_channelsstring[]No販売チャネル
pia_base_urlstringNoチケットぴあURL
promo_textstringNoプロモーションテキスト

レスポンス: EventResponse


PUT /api/events/{event_id}

イベント更新。指定フィールドのみ更新 (部分更新)。

認証: Admin 監査ログ: あり

リクエストボディ (EventUpdate): EventCreate と同じフィールド (全てOptional) + status (EventStatus)

レスポンス: EventResponse


DELETE /api/events/{event_id}

イベント削除。

認証: Admin 監査ログ: あり

レスポンス: SuccessResponse


GET /api/events/{event_id}/players

イベントにアサインされた選手一覧。ノルマ・達成率を含む。

認証: 必要

レスポンス:

[
  {
    "player_id": "uuid",
    "player_name": "選手名",
    "gym": "ジム名",
    "weight_class": "階級",
    "target_quantity": 100,
    "target_amount": 500000,
    "reward_rate": 0.1,
    "sold_quantity": 45,
    "sold_amount": 225000,
    "achievement_rate": 45.0
  }
]

POST /api/events/{event_id}/players

選手をイベントにアサインし、ノルマ (販売目標) を設定。

認証: Admin 監査ログ: あり

リクエストボディ (NormaSet):

フィールド必須説明
player_idstringYes選手UUID
event_idstringYesイベントUUID
target_quantityintYes目標枚数
target_amountintYes目標金額 (JPY)

レスポンス: SuccessResponse


PUT /api/events/{event_id}/players/{player_id}

選手のノルマ更新。

認証: Admin 監査ログ: あり

リクエストボディ: NormaSet レスポンス: SuccessResponse


GET /api/events/{event_id}/sales-stats

イベントの販売統計。ルート別・選手別・席種別の内訳を返す。

認証: 必要

レスポンス:

{
  "event_id": "uuid",
  "total_quantity": 200,
  "total_amount": 1000000,
  "by_route": [
    {"route": "lp", "quantity": 100, "amount": 500000}
  ],
  "by_player": [
    {"player_id": "uuid", "player_name": "選手名", "quantity": 50, "amount": 250000}
  ],
  "by_seat_type": [
    {"seat_type": "S席", "quantity": 80, "amount": 640000}
  ]
}

4. Tickets (チケット)

GET /api/tickets/

チケット一覧取得。Player ロールの場合は自分のチケットのみ返す。

認証: 必要

クエリパラメータ:

パラメータ必須説明
event_idstringNoイベントフィルタ
player_idstringNo選手フィルタ
routestringNoルートフィルタ
pageintNoページ番号
per_pageintNo件数

レスポンス (TicketResponse[]):

フィールド説明
idstringチケットUUID
fan_idstring?ファンUUID
player_idstring選手UUID
event_idstringイベントUUID
quantityint枚数
routeTicketRoute販売ルート
seat_typestring席種
amountint金額 (JPY)
paidbool支払済フラグ
paid_datedatetime?支払日
buyer_namestring購入者名
memostringメモ
purchased_atdatetime購入日時

GET /api/tickets/{ticket_id}

チケット詳細。Player は自分のチケットのみアクセス可。

認証: 必要 レスポンス: TicketResponse


POST /api/tickets/manual-sale

手動チケット販売登録 (会場現金販売等)。

認証: 必要 監査ログ: あり

リクエストボディ (ManualSaleCreate):

フィールド必須説明
player_idstringYes選手UUID
event_idstringYesイベントUUID
fan_idstringNoファンUUID
quantityintNo枚数 (デフォルト1, 最小1)
seat_typestringYes席種名
amountintYes金額 (JPY, 0以上)
buyer_namestringNo購入者名
memostringNoメモ
paidboolNo支払済フラグ (デフォルトfalse)

レスポンス: TicketResponse

備考: 販売通知が選手に自動送信される。


PUT /api/tickets/{ticket_id}

チケット更新。

認証: 必要 監査ログ: あり リクエストボディ: ManualSaleCreate レスポンス: TicketResponse


DELETE /api/tickets/{ticket_id}

チケット削除。Player は自分のチケットのみ削除可。

認証: 必要 監査ログ: あり レスポンス: SuccessResponse


POST /api/tickets/webhook/pia

チケットぴあからのWebhookコールバック。HMAC-SHA256署名検証あり。

認証: X-Webhook-Signature ヘッダーによるHMAC-SHA256署名検証 監査ログ: あり

ヘッダー:

ヘッダー必須説明
X-Webhook-SignatureYesHMAC-SHA256署名

リクエストボディ (WebhookPayload):

フィールド必須説明
event_idstringYes外部イベントID
order_idstringYesぴあ注文ID
buyer_namestringYes購入者名
seat_typestringYes席種名
quantityintYes枚数
amountintYes金額 (JPY)
player_refstringNo選手参照コード
purchased_atstringYes購入日時 (ISO8601)

レスポンス: SuccessResponse


5. Players (選手)

GET /api/players/

選手一覧取得。

認証: Admin または Association

クエリパラメータ:

パラメータ必須デフォルト説明
pageintNo1ページ番号
per_pageintNo20件数

レスポンス (PlayerResponse[]):

フィールド説明
idstring選手UUID
login_idstringログインID
namestring表示名
gymstring所属ジム
weight_classstring階級
profile_image_urlstring?プロフィール画像URL
sns_linksobjectSNSリンク
slugstringURLスラグ
is_lockedboolロック状態
rolePlayerRoleロール
created_atdatetime作成日時
updated_atdatetime更新日時

GET /api/players/me

認証済み選手の自分のプロフィール取得。

認証: 必要 レスポンス: PlayerResponse


PUT /api/players/me

認証済み選手の自分のプロフィール更新。

認証: 必要 監査ログ: あり

リクエストボディ (PlayerUpdate):

フィールド必須説明
namestringNo表示名
gymstringNo所属ジム
weight_classstringNo階級
phonestringNo電話番号 (AES-256暗号化)
profile_image_urlstringNoプロフィール画像URL
sns_linksobjectNoSNSリンク
slugstringNoURLスラグ

レスポンス: PlayerResponse


POST /api/players/me/image

プロフィール画像アップロード (Supabase Storage)。

認証: 必要 監査ログ: あり Content-Type: multipart/form-data

リクエスト:

フィールド必須説明
fileUploadFileYes画像ファイル (image/* のみ)

レスポンス: SuccessResponse


GET /api/players/public/{slug}

選手の公開プロフィールページ。認証不要。

認証: 不要 パスパラメータ: slug (URLスラグ)

レスポンス (PlayerPublicResponse):

フィールド説明
namestring表示名
gymstring所属ジム
weight_classstring階級
profile_image_urlstring?プロフィール画像URL
sns_linksobjectSNSリンク
slugstringURLスラグ

GET /api/players/{player_id}

選手詳細取得。Player は自分のプロフィールのみアクセス可。

認証: 必要 レスポンス: PlayerResponse


GET /api/players/{player_id}/qr/{event_id}

選手のLP用QRコード (PNG画像) を生成。

認証: 必要 パスパラメータ: player_id (UUID), event_id (UUID) レスポンス: image/png (StreamingResponse)

備考: QRコードのURLは https://sb-ticket.com/lp/{event_id}?ref={slug} 形式。


POST /api/players/

選手アカウント作成。

認証: Admin 監査ログ: あり

リクエストボディ (PlayerCreate):

フィールド必須説明
login_idstringYesログインID
namestringYes表示名
passwordstringYes初期パスワード (8文字以上)
gymstringNo所属ジム
weight_classstringNo階級
phonestringNo電話番号 (AES-256暗号化)
rolePlayerRoleNoロール (デフォルト: player)

レスポンス: PlayerResponse


PUT /api/players/{player_id}

選手情報更新。

認証: Admin 監査ログ: あり リクエストボディ: PlayerUpdate レスポンス: PlayerResponse


DELETE /api/players/{player_id}

選手論理削除 (アカウントロック)。

認証: Admin 監査ログ: あり レスポンス: SuccessResponse


6. Landing Pages (LP)

GET /api/lps/

LP一覧取得。

認証: 必要

クエリパラメータ:

パラメータ必須説明
event_idstringNoイベントフィルタ
statusLPStatusNoステータスフィルタ

レスポンス (LPResponse[]):

フィールド説明
idstringLP UUID
event_idstringイベントUUID
html_contentstringHTML コンテンツ
statusLPStatusステータス
hero_image_urlstring?ヒーロー画像URL
published_atdatetime?公開日時
created_atdatetime作成日時
updated_atdatetime更新日時

GET /api/lps/{lp_id}

LP詳細取得。lp_id または event_id で検索可能。

認証: 必要 レスポンス: LPResponse


POST /api/lps/generate/{event_id}

Claude AIを使用してLPを自動生成。

認証: Admin

クエリパラメータ:

パラメータ必須説明
hero_image_urlstringNoヒーロー画像URL
additional_promptstringNo追加プロンプト

レスポンス: LPResponse

備考: イベント・選手データを取得し、Claude APIでHTMLを生成して保存。


POST /api/lps/generate

LP生成 (リクエストボディでパラメータ指定)。

認証: 必要

リクエストボディ (LPGenerateRequest):

フィールド必須説明
event_idstringYesイベントUUID
player_idstringYes選手UUID
hero_image_urlstringNoヒーロー画像URL
additional_promptstringNo追加プロンプト

レスポンス: LPResponse


PUT /api/lps/{lp_id}

LPコンテンツ・ヒーロー画像を更新。

認証: Admin 監査ログ: あり

リクエストボディ (LPUpdateRequest):

フィールド必須説明
html_contentstringNoHTMLコンテンツ
hero_image_urlstringNoヒーロー画像URL

レスポンス: LPResponse


POST /api/lps/{lp_id}/publish

LPを公開状態にする。

認証: Admin 監査ログ: あり

レスポンス: LPResponse

備考: LP公開時に全選手へ通知が送信される。既に公開済みの場合は400エラー。


POST /api/lps/{lp_id}/unpublish

LPを非公開にする。

認証: Admin 監査ログ: あり レスポンス: LPResponse


GET /api/lps/{lp_id}/preview

LPのHTMLプレビュー。

認証: 必要 レスポンス: text/html (HTMLResponse)


7. Fans (ファン)

GET /api/fans/

ファン一覧取得。Player は自分のファンのみ。

認証: 必要

クエリパラメータ:

パラメータ必須説明
player_idstringNo選手フィルタ (Admin のみ)
pageintNoページ番号
per_pageintNo件数

レスポンス (FanResponse[]):

フィールド説明
idstringファンUUID
player_idstring選手UUID
namestringファン名
has_phonebool電話番号登録済
has_emailboolメール登録済
memostringメモ
created_atdatetime作成日時

GET /api/fans/dig-out

掘り起こしリスト。最近チケットを購入していないファンの一覧。

認証: 必要

クエリパラメータ:

パラメータ必須デフォルト説明
player_idstringNo-選手フィルタ
days_thresholdintNo90最終購入からの日数閾値

レスポンス (DigOutListResponse[]):

フィールド説明
fan_idstringファンUUID
fan_namestringファン名
last_purchase_datedatetime?最終購入日
total_purchasesint購入回数
total_amountint購入総額 (JPY)
days_since_last_purchaseint?最終購入からの日数

GET /api/fans/{fan_id}

ファン詳細取得。Player は自分のファンのみアクセス可。

認証: 必要 レスポンス: FanResponse


GET /api/fans/{fan_id}/purchases

ファンの購入履歴。イベント名付きのチケット一覧。

認証: 必要

レスポンス:

[
  {
    "ticket_id": "uuid",
    "event_id": "uuid",
    "event_name": "イベント名",
    "seat_type": "S席",
    "quantity": 2,
    "amount": 16000,
    "route": "lp",
    "paid": true,
    "purchased_at": "2026-03-01T12:00:00Z"
  }
]

POST /api/fans/

ファン登録。電話番号・メールはAES-256で暗号化。

認証: 必要 監査ログ: あり

リクエストボディ (FanCreate):

フィールド必須説明
player_idstringYes選手UUID
namestringYesファン名
phonestringNo電話番号 (AES-256暗号化)
emailstringNoメール (AES-256暗号化)
memostringNoメモ

レスポンス: FanResponse


PUT /api/fans/{fan_id}

ファン更新。

認証: 必要 監査ログ: あり

リクエストボディ (FanUpdate):

フィールド必須説明
namestringNoファン名
phonestringNo電話番号
emailstringNoメール
memostringNoメモ

レスポンス: FanResponse


DELETE /api/fans/{fan_id}

ファン削除。Player は自分のファンのみ削除可。

認証: 必要 監査ログ: あり レスポンス: SuccessResponse


8. Sponsors (スポンサー)

GET /api/sponsors/

スポンサー一覧取得。

認証: 必要 アクセス制御: Admin=全件, Player=自分の紐付け分, Association=全件

クエリパラメータ:

パラメータ必須説明
player_idstringNo選手フィルタ
concept_statusConceptStatusNoパイプラインステータスフィルタ
searchstringNo会社名検索
pageintNoページ番号
per_pageintNo件数

レスポンス (SponsorResponse[]):

フィールド説明
idstringスポンサーUUID
player_idstring選手UUID
company_namestring会社名
industrystring業種
contact_namestring担当者名
has_contact_phonebool電話番号登録済
has_contact_emailboolメール登録済
contract_amountint契約金額 (JPY)
contract_startdate?契約開始日
contract_enddate?契約終了日
concept_statusConceptStatusパイプラインステータス
memostringメモ
is_public_to_associationbool協会公開フラグ
created_atdatetime作成日時

GET /api/sponsors/{sponsor_id}

スポンサー詳細取得。Player は自分の紐付けのみ。

認証: 必要 レスポンス: SponsorResponse


POST /api/sponsors/

スポンサー作成。連絡先はAES-256暗号化。

認証: Admin 監査ログ: あり

リクエストボディ (SponsorCreate):

フィールド必須説明
player_idstringYes選手UUID
company_namestringYes会社名
industrystringNo業種
contact_namestringNo担当者名
contact_phonestringNo電話番号 (暗号化)
contact_emailstringNoメール (暗号化)
contract_amountintNo契約金額 (JPY)
contract_startdateNo契約開始日
contract_enddateNo契約終了日
memostringNoメモ

レスポンス: SponsorResponse


PUT /api/sponsors/{sponsor_id}

スポンサー更新。

認証: Admin 監査ログ: あり リクエストボディ: SponsorUpdate (SponsorCreate と同じフィールド + concept_status, is_public_to_association, 全てOptional) レスポンス: SponsorResponse


DELETE /api/sponsors/{sponsor_id}

スポンサー論理削除 (deleted_at タイムスタンプを設定)。

認証: Admin 監査ログ: あり レスポンス: SuccessResponse


PUT /api/sponsors/{sponsor_id}/concept-status

コンセプトパイプラインステータス更新。

認証: Admin または Association 監査ログ: あり

クエリパラメータ:

パラメータ必須説明
concept_statusConceptStatusYes新しいステータス
concept_memostringNoステータス変更メモ

レスポンス: SponsorResponse


POST /api/sponsors/{sponsor_id}/publish

協会への公開/非公開をトグル。

認証: Admin または Association 監査ログ: あり

クエリパラメータ:

パラメータ必須説明
is_publicboolYes協会への公開フラグ

レスポンス: SponsorResponse


POST /api/sponsors/{sponsor_id}/approve

スポンサーの公開承認。

認証: Admin 監査ログ: あり

クエリパラメータ:

パラメータ必須説明
is_approvedboolYes公開承認フラグ

レスポンス: SponsorResponse


9. Kickbacks (キックバック)

GET /api/kickbacks/

キックバック一覧。Player はアクセス不可 (403)。

認証: Admin/Association (Player は403)

クエリパラメータ:

パラメータ必須説明
sponsor_idstringNoスポンサーフィルタ
paidboolNo支払済フィルタ
pageintNoページ番号
per_pageintNo件数

レスポンス (KickbackResponse[]):

フィールド説明
idstringキックバックUUID
sponsor_idstringスポンサーUUID
player_idstring選手UUID
contract_amountint契約金額 (JPY)
kickback_ratefloatキックバック率 (0.0-1.0)
kickback_amountintキックバック金額 (自動計算)
payment_due_datedate?支払期日
paid_flagbool支払済フラグ
paid_datedate?支払日
memostringメモ
created_atdatetime作成日時

GET /api/kickbacks/{kickback_id}

キックバック詳細。Player はアクセス不可 (403)。

認証: Admin/Association レスポンス: KickbackResponse


POST /api/kickbacks/

キックバック作成。kickback_amountcontract_amount * kickback_rate で自動計算。

認証: Admin/Association 監査ログ: あり

リクエストボディ (KickbackCreate):

フィールド必須説明
sponsor_idstringYesスポンサーUUID
player_idstringYes選手UUID
contract_amountintYes契約金額 (JPY)
kickback_ratefloatYesキックバック率 (0.0-1.0)
payment_due_datedateNo支払期日
memostringNoメモ

レスポンス: KickbackResponse


PUT /api/kickbacks/{kickback_id}

キックバック更新。金額再計算あり。

認証: Admin/Association 監査ログ: あり リクエストボディ: KickbackCreate レスポンス: KickbackResponse


POST /api/kickbacks/{kickback_id}/mark-paid

キックバックを支払済にマーク。

認証: Admin/Association 監査ログ: あり レスポンス: SuccessResponse


GET /api/kickbacks/summary

キックバックサマリー統計。Player はアクセス不可 (403)。

認証: Admin/Association

レスポンス:

{
  "total_contract_amount": 10000000,
  "total_kickback_amount": 1000000,
  "paid_amount": 600000,
  "unpaid_amount": 400000,
  "total_records": 15
}

GET /api/kickbacks/export-csv

キックバックデータをCSVエクスポート。暗号化された振込先情報を復号して出力。

認証: Admin 監査ログ: あり レスポンス: text/csv (StreamingResponse, ファイル名: kickbacks_export.csv)

CSV列: ID, Sponsor, Player, Contract Amount, Kickback Rate, Kickback Amount, Payment Due Date, Paid, Paid Date, Transfer Info, Memo, Created At


10. Notifications (通知)

GET /api/notifications/

通知一覧取得 (自分宛て)。

認証: 必要

クエリパラメータ:

パラメータ必須説明
unread_onlyboolNo未読のみ
typeNotificationTypeNo通知種別フィルタ
pageintNoページ番号
per_pageintNo件数

レスポンス (NotificationResponse[]):

フィールド説明
idstring通知UUID
typeNotificationType通知種別
titlestringタイトル
bodystring本文
is_readbool既読フラグ
sent_atdatetime?送信日時
created_atdatetime作成日時

GET /api/notifications/unread-count

未読通知数を取得。

認証: 必要

レスポンス:

{
  "unread_count": 5
}

POST /api/notifications/{notification_id}/read

通知を既読にする。

認証: 必要 レスポンス: SuccessResponse


POST /api/notifications/read-all

全通知を既読にする。

認証: 必要 レスポンス: SuccessResponse


POST /api/notifications/send

通知を送信。SMSの場合はTwilio経由、Web Pushの場合はプッシュサービス経由。

認証: Admin 監査ログ: あり

リクエストボディ (SendNotificationRequest):

フィールド必須説明
player_idstringNo送信先選手UUID
fan_idstringNo送信先ファンUUID
typeNotificationTypeYes通知種別
titlestringYesタイトル
bodystringYes本文

レスポンス: SuccessResponse


POST /api/notifications/bulk-deadline

販売締切が近いイベントの選手へ一斉アラート送信。

認証: Admin 監査ログ: あり

リクエストボディ (BulkDeadlineRequest):

フィールド必須デフォルト説明
days_aheadintNo3締切何日前にアラートするか (1-30)

レスポンス:

{
  "events_notified": 3,
  "sent_count": 3
}

11. Rankings (ランキング)

GET /api/rankings/sales

チケット販売ランキング。Admin は枚数・金額も表示、それ以外は順位のみ。

認証: 必要

クエリパラメータ:

パラメータ必須デフォルト説明
event_idstringNo-イベントフィルタ
limitintNo20取得件数 (最大100)

レスポンス (SalesRankingEntry[]):

フィールド説明
rankint順位
player_idstring選手UUID
player_namestring選手名
player_slugstringURLスラグ
profile_image_urlstring?プロフィール画像URL
total_quantityint?販売枚数 (Admin のみ)
total_amountint?販売金額 (Admin のみ)

GET /api/rankings/views

LPページビューランキング。Admin はビュー数も表示。

認証: 必要

クエリパラメータ:

パラメータ必須説明
event_idstringNoイベントフィルタ
periodstringNo期間 (daily, weekly, monthly)
limitintNo取得件数

レスポンス (PageViewRankingEntry[]):

フィールド説明
rankint順位
player_idstring選手UUID
player_namestring選手名
total_viewsint?ビュー数 (Admin のみ)

GET /api/rankings/daily/{event_id}

イベントの日別販売データ。

認証: 必要

クエリパラメータ:

パラメータ必須説明
start_datedateNo開始日
end_datedateNo終了日

レスポンス (DailySalesEntry[]):

フィールド説明
datedate日付
quantityint販売枚数
amountint販売金額 (JPY)

GET /api/rankings/daily

前日の販売ランキング。

認証: 必要

レスポンス (DailyRankingEntry[]):

フィールド説明
rankint順位
player_idstring選手UUID
player_namestring選手名
datestring日付 (前日)
total_quantityint?販売枚数 (Admin のみ)
total_amountint?販売金額 (Admin のみ)

12. Admin (管理者)

全エンドポイントに Admin ロールが必要。ルーター全体に require_role(PlayerRole.ADMIN) が適用されている。

GET /api/admin/dashboard

管理ダッシュボードの統計情報。

認証: Admin

レスポンス (DashboardStats):

フィールド説明
total_playersint登録選手数
total_eventsintイベント数
total_tickets_soldint販売チケット枚数
total_revenueint総売上 (JPY)
active_lpsint公開中LP数
total_fansintファン数
total_sponsorsintスポンサー数
pending_kickbacksint未払いキックバック数

GET /api/admin/audit-logs

監査ログ照会。

認証: Admin

クエリパラメータ:

パラメータ必須説明
actor_idstringNo操作者フィルタ
actionstringNoアクションフィルタ
resource_typestringNoリソースタイプフィルタ
pageintNoページ番号
per_pageintNo件数 (デフォルト50, 最大200)

レスポンス (AuditLogEntry[]):

フィールド説明
idstringログID
actor_idstring操作者ID
actor_rolestring操作者ロール
actionstringアクション
resource_typestringリソースタイプ
resource_idstringリソースID
detailsobject詳細情報
ip_addressstring?IPアドレス
created_atstring日時

GET /api/admin/players

選手管理一覧。チケット販売数を含む。

認証: Admin

レスポンス (PlayerManagementResponse[]):

フィールド説明
idstring選手UUID
login_idstringログインID
namestring表示名
rolestringロール
is_lockedboolロック状態
failed_attemptsintログイン失敗回数
total_tickets_soldint販売チケット数

POST /api/admin/players

選手アカウント作成。

認証: Admin 監査ログ: あり リクエストボディ: PlayerCreate レスポンス: PlayerResponse


POST /api/admin/players/{player_id}/lock

選手アカウントをロック (ログイン不可にする)。

認証: Admin レスポンス: SuccessResponse


POST /api/admin/players/{player_id}/unlock

選手アカウントのロックを解除し、失敗回数をリセット。

認証: Admin レスポンス: SuccessResponse


POST /api/admin/players/{player_id}/reset-password

選手のパスワードを一時パスワードにリセット。

認証: Admin 監査ログ: あり レスポンス: SuccessResponse (一時パスワードがメッセージに含まれる)


13. Concept Pipeline (営業パイプライン)

スポンサー営業パイプラインの管理。全エンドポイントに Association ロールが必要。

GET /api/concept/leads

リード (営業案件) 一覧。暗号化された連絡先を復号して返す。

認証: Association

クエリパラメータ:

パラメータ必須説明
statusConceptStatusNoステータスフィルタ
searchstringNo会社名検索
player_idstringNo選手フィルタ
pageintNoページ番号
per_pageintNo件数

レスポンス (LeadResponse[]):

フィールド説明
sponsor_idstringスポンサーUUID
company_namestring会社名
industrystring業種
contact_namestring担当者名
contact_phonestring?電話番号 (復号済)
contact_emailstring?メール (復号済)
player_idstring担当選手UUID
player_namestring担当選手名
concept_statusConceptStatusステータス
concept_memostringメモ
contract_amountint契約金額 (JPY)
is_public_to_associationbool協会公開フラグ
created_atdatetime作成日時

GET /api/concept/leads/pipeline-summary

パイプラインサマリー (ステージ別件数と潜在金額)。

認証: Association

レスポンス (PipelineSummary):

フィールド説明
leadintリード数
proposalint提案中数
negotiationint交渉中数
contractedint契約済数
declinedint辞退数
total_potential_valueint潜在合計金額 (JPY)

PUT /api/concept/leads/{sponsor_id}/advance

リードを次のステージへ進行。lead -> proposal -> negotiation -> contracted

認証: Association 監査ログ: あり レスポンス: LeadResponse

エラー: 辞退済み・最終ステージの場合は400エラー。


PUT /api/concept/leads/{sponsor_id}/status

リードのステータスを直接設定。

認証: Association 監査ログ: あり

クエリパラメータ:

パラメータ必須説明
concept_statusConceptStatusYes新しいステータス
concept_memostringNoメモ

レスポンス: LeadResponse


POST /api/concept/leads/{sponsor_id}/publish

協会への公開/非公開トグル。

認証: Association 監査ログ: あり

クエリパラメータ:

パラメータ必須説明
is_publicboolYes公開フラグ

レスポンス: SuccessResponse


GET /api/concept/kickbacks

キックバック一覧 (営業ビュー)。

認証: Association

クエリパラメータ:

パラメータ必須説明
sponsor_idstringNoスポンサーフィルタ
paidboolNo支払済フィルタ
pageintNoページ番号
per_pageintNo件数

レスポンス: KickbackResponse[]


POST /api/concept/kickbacks

キックバック作成 (営業側)。

認証: Association 監査ログ: あり リクエストボディ: KickbackCreate レスポンス: KickbackResponse


14. Rewards (報酬)

LP経由チケット販売の選手報酬 (レベニューシェア) 管理。

GET /api/rewards/

報酬一覧。Admin は全件、Player は自分の分のみ。

認証: 必要

クエリパラメータ:

パラメータ必須説明
event_idstringNoイベントフィルタ
pageintNoページ番号
per_pageintNo件数

レスポンス (RewardResponse[]):

フィールド説明
idstring報酬UUID
player_idstring選手UUID
player_namestring選手名
event_idstringイベントUUID
event_namestringイベント名
lp_idstringLP UUID
total_revenueintLP総売上 (JPY)
reward_ratefloat報酬率
reward_amountint報酬金額 (JPY)
statusstringステータス (pending/confirmed/paid)
paid_flagbool支払済フラグ
paid_datedatetime?支払日
memostringメモ
created_atdatetime作成日時

GET /api/rewards/my

自分の収入サマリー。手売り売上とLP報酬の合計。

認証: 必要

レスポンス (PlayerIncomeSummary):

フィールド説明
player_idstring選手UUID
personal_sales_totalint手売り合計 (JPY)
lp_reward_confirmedint確定済みLP報酬 (JPY)
lp_reward_estimatedint見込みLP報酬 (JPY)
cumulative_receivedint受取済み合計 (JPY)
pending_amountint未払い確定報酬 (JPY)

POST /api/rewards/calculate/{event_id}

イベントの報酬を一括計算。LP経由販売 x 報酬率で算出し、player_rewards テーブルにupsert。

認証: Admin 監査ログ: あり

レスポンス: list[dict] (計算結果の配列)


POST /api/rewards/{reward_id}/mark-paid

報酬を支払済にマーク。選手に支払完了通知を送信。

認証: Admin 監査ログ: あり レスポンス: SuccessResponse

備考: アプリ内通知も自動作成される。


GET /api/rewards/summary

報酬サマリー。全体の支払済/未払い合計とイベント別内訳。

認証: Admin

レスポンス (RewardSummary):

フィールド説明
total_unpaidint未払い合計 (JPY)
total_paidint支払済合計 (JPY)
total_rewardsint報酬総額 (JPY)
by_eventlist[dict]イベント別内訳

by_event の各要素:

{
  "event_id": "uuid",
  "event_name": "イベント名",
  "paid": 100000,
  "unpaid": 50000,
  "total": 150000
}

ミドルウェア

ミドルウェア説明
CORS許可オリジン: localhost:3000, sb-ticket.com, sb-ticket-dev.aidreams-factory.com
SecurityHeadersセキュリティヘッダー付与
RateLimitレートリミット
Audit監査ログ記録

セキュリティ

項目実装
認証JWT (HttpOnly Cookie, SameSite=Lax, Secure)
パスワードbcrypt (cost 12)
個人情報暗号化AES-256 (電話番号, メール, 振込先情報)
Webhook検証HMAC-SHA256署名
アカウントロック5回ログイン失敗で自動ロック
RBACロールベースアクセス制御 (player, admin, association)
監査ログ全変更操作を記録