happa API 仕様書 v1.0¶
概要¶
happa システムの API を Next.js から分離し、FastAPI で再構築するための仕様書です。この API は大学祭などのイベント管理システムのバックエンドとして機能します。
システム概要¶
- イベント管理: 千葉大祭などの大規模イベントの管理
- 団体管理: サークルや団体の情報管理
- 企画管理: 各団体が実施する企画の申請・承認・管理
- リソース配分: 会場、予算、物品などのリソース割り当て
- スケジュール管理: 説明会、イベントスケジュールの管理とチェックイン機能
- サポート: 問い合わせ管理とチャット機能
技術スタック¶
推奨技術¶
- フレームワーク: FastAPI 0.104+
- データベース: MySQL 8.0+ with Prisma ORM 互換
- 認証: Auth0 (OAuth2)
- ORM: SQLAlchemy 2.0+ または Tortoise ORM
- バリデーション: Pydantic v2
- 非同期処理: asyncio
- ドキュメント: OpenAPI 3.0 (FastAPI 自動生成)
環境変数¶
DATABASE_URL=mysql://user:password@host:port/database
AUTH0_DOMAIN=your-tenant.auth0.com
AUTH0_CLIENT_ID=your-client-id
AUTH0_CLIENT_SECRET=your-client-secret
AUTH0_AUDIENCE=your-api-audience
NODE_ENV=production|development
認証・認可¶
認証方式¶
- Auth0 OAuth2: Bearer Token 認証
- 開発モード:
NODE_ENV=development時はモックユーザーで認証バイパス可能
ユーザーロール(段階的廃止予定)¶
class UserRole(str, Enum):
USER = "User" # 一般ユーザー(デフォルト)
LIMITED_ADMIN = "LimitedAdmin" # 制限付き管理者(廃止予定)
READ_ONLY_ADMIN = "ReadOnlyAdmin" # 読み取り専用管理者(廃止予定)
FULL_ACCESS_ADMIN = "FullAccessAdmin" # 完全管理者(廃止予定)
注意: グローバルロールは段階的に廃止し、リソースレベル権限システムに移行します。
リソースレベル権限システム¶
リソースタイプ¶
class ResourceType(str, Enum):
PROJECT = "PROJECT" # イベント全体(例: 千葉大祭2024)
CIRCLE_PROJECT = "CIRCLE_PROJECT" # 個別企画
権限の種類¶
class Permission(str, Enum):
READ = "READ" # 読み取り
WRITE = "WRITE" # 書き込み・更新
DELETE = "DELETE" # 削除
MANAGE_MEMBERS = "MANAGE_MEMBERS" # メンバー管理
MANAGE_PERMISSIONS = "MANAGE_PERMISSIONS" # 権限管理
APPROVE = "APPROVE" # 承認操作
CHECKIN = "CHECKIN" # チェックイン操作
ALLOCATE_RESOURCES = "ALLOCATE_RESOURCES" # リソース割り当て
VIEW_PRIVATE = "VIEW_PRIVATE" # 非公開情報の閲覧
標準ロールテンプレート¶
Project用:
- ProjectAdmin: 全権限(READ, WRITE, DELETE, MANAGE_MEMBERS, MANAGE_PERMISSIONS, APPROVE, ALLOCATE_RESOURCES, VIEW_PRIVATE)
- ProjectManager: 管理権限(READ, WRITE, APPROVE, ALLOCATE_RESOURCES, VIEW_PRIVATE)
- ProjectEditor: 編集権限(READ, WRITE, VIEW_PRIVATE)
- ProjectViewer: 閲覧のみ(READ)
CircleProject用:
- Manager: 企画管理者(READ, WRITE, DELETE, MANAGE_MEMBERS, MANAGE_PERMISSIONS, CHECKIN, VIEW_PRIVATE)
- Editor: 企画編集者(READ, WRITE, CHECKIN, VIEW_PRIVATE)
- Member: 一般メンバー(READ, CHECKIN)
- Viewer: 閲覧のみ(READ)
認証レベル¶
- requireAuth: ログインユーザー(全ロール)
- requireAdminPlus: 管理者以上(LIMITED_ADMIN, READ_ONLY_ADMIN, FULL_ACCESS_ADMIN)※廃止予定
- requireAdmin: 完全管理者のみ(FULL_ACCESS_ADMIN)※廃止予定
- requireCircleProjectManager: 企画管理者(企画の最初のメンバー)※廃止予定
- requireCircleProjectMember: 企画メンバー※廃止予定
- requireResourcePermission(resourceType, resourceId, permissions): リソースレベル権限チェック(新規)
自動ユーザー作成¶
- 初回ログイン時に Auth0 の
subとemailからユーザーを自動作成 @student.gs.chiba-u.jpドメインのメールアドレスから学籍番号を抽出- デフォルトロールは
User
データモデル¶
主要エンティティ¶
1. User (ユーザー)¶
{
"id": "uuid",
"studentId": "string | null", # 学籍番号
"auth0Id": "string | null", # Auth0 sub
"name": "string | null",
"email": "string",
"role": "UserRole"
}
2. Project (イベント)¶
{
"prefix": "string", # 一意識別子(例: "chibafes2024")
"name": "string", # イベント名
"owner": "string | null",
"startAt": "datetime | null",
"endAt": "datetime | null",
"closeRegisterAt": "datetime | null",
"isClose": "boolean",
"notificationWebhook": "string | null",
"allowedCategories": "list[Category] | null", # JSON配列
"allowedProjectTypes": "list[string] | null" # JSON配列
}
3. Circle (団体)¶
{
"circleId": "string", # 団体ID
"name": "string",
"name_kana": "string",
"isOfficial": "boolean" # 公認団体フラグ
}
4. CircleProject (企画)¶
{
"id": "uuid",
"parentPrefix": "string", # FK to Project
"circleId": "string", # FK to Circle
"name": "string",
"memo": "string | null",
"location": "string",
"projectType": "string",
"category": "Category | null",
"areaCode": "AreaCode | null",
"areaNumber": "string | null",
"pamphletNumber": "string | null",
"beforeDay": "boolean",
"firstDay": "boolean",
"secondDay": "boolean",
"thirdDay": "boolean",
"isArchived": "boolean",
"archivedAt": "datetime | null",
"status": "CircleProjectStatus", # DRAFT, APPROVED, REJECTED
"applicationGroupId": "uuid | null", # 申請グループ化用
"applicationReason": "string | null"
}
5. Allocation (リソース割り当て)¶
{
"id": "uuid",
"parentPrefix": "string",
"name": "string",
"provider": "string",
"max": "int",
"maxPerOne": "int | null",
"price": "int",
"unit": "string | null",
"category": "AllocationCategory | null",
"tagId": "uuid | null"
}
6. Schedule (スケジュール)¶
{
"id": "uuid",
"parentPrefix": "string",
"parentFolderId": "uuid | null",
"name": "string",
"scheduleType": "ScheduleType", # SCHEDULE, TASK
"startTime": "datetime | null",
"endTime": "datetime | null",
"location": "string",
"description": "string | null",
"isPublishToCircle": "boolean",
"isCheckinEnabled": "boolean",
"isAllowSelfCheckin": "boolean",
"isPublicCheckinStatus": "boolean",
"isRequireManager": "boolean"
}
Enum 定義¶
class Category(str, Enum):
FOOD = "FOOD" # 飲食
EXHIBITION = "EXHIBITION" # 展示
MUSIC = "MUSIC" # 音楽
PERFORMANCE = "PERFORMANCE" # パフォーマンス
PARTICIPATORY = "PARTICIPATORY" # 参加型
MERCHANDISE = "MERCHANDISE" # 物販
OTHER = "OTHER" # その他
class AreaCode(str, Enum):
T = "T" # 工北
R = "R" # 工南
S = "S" # 理学
L = "L" # 文法
D = "D" # 人社・院棟
K = "K" # 語らいの森
H = "H" # 本部
E = "E" # 教育
G = "G" # 普遍
class CircleProjectStatus(str, Enum):
DRAFT = "DRAFT" # 申請中(仮企画)
APPROVED = "APPROVED" # 承認済み(正式企画)
REJECTED = "REJECTED" # 却下
class AllocationCategory(str, Enum):
BASE_PRICING = "BASE_PRICING"
PROJECT_OPTION_PRICING = "PROJECT_OPTION_PRICING"
FOOD_OPTION_PRICING = "FOOD_OPTION_PRICING"
ITEM_RENTAL_PRICING = "ITEM_RENTAL_PRICING"
class CheckinStatus(str, Enum):
ATTENDANCE = "ATTENDANCE"
ABSENCE = "ABSENCE"
TENTATIVE = "TENTATIVE"
UNSET = "UNSET"
class CheckinMethod(str, Enum):
ADMIN_PANEL = "ADMIN_PANEL"
QR_SCAN = "QR_SCAN"
LIST_SELECTION = "LIST_SELECTION"
SELF_CHECKIN = "SELF_CHECKIN"
class SupportCaseStatus(str, Enum):
OPEN = "OPEN"
CLOSE = "CLOSE"
FREEZE = "FREEZE"
API エンドポイント一覧¶
ベース URL: /api
1. 認証・ユーザー管理¶
GET /api/user¶
現在のユーザー情報を取得または作成
認証: requireAuth
レスポンス:
GET /api/user/list¶
全ユーザーリスト取得
認証: requireAdminPlus
レスポンス:
{
"users": [
{
"id": "uuid",
"studentId": "ABC123",
"email": "user@example.com",
"role": "User"
}
]
}
PUT /api/user/{id}/role¶
ユーザーロール更新
認証: requireAdmin
リクエストボディ:
2. プロジェクト管理¶
GET /api/project?prefix={prefix}¶
プロジェクト詳細取得(企画一覧含む)
認証: requireAdminPlus
パラメータ:
prefix(required): プロジェクト識別子
レスポンス:
{
"projects": {
"prefix": "chibafes2024",
"name": "千葉大祭2024",
"owner": "実行委員会",
"startAt": "2024-11-01T00:00:00Z",
"endAt": "2024-11-03T23:59:59Z",
"circleProjects": [...]
}
}
GET /api/project/list¶
全プロジェクトリスト取得
認証: requireAdminPlus
GET /api/project/constraints?prefix={prefix}¶
申請可能なカテゴリーと企画種別取得
認証: なし(公開)
レスポンス:
POST /api/project¶
新規プロジェクト作成
認証: requireAdmin
リクエストボディ:
{
"prefix": "chibafes2025",
"name": "千葉大祭2025",
"owner": "実行委員会",
"startAt": "2025-11-01T00:00:00Z",
"endAt": "2025-11-03T23:59:59Z",
"closeRegisterAt": "2025-10-01T23:59:59Z",
"notificationWebhook": "https://webhook.example.com",
"allowedCategories": ["FOOD", "EXHIBITION"],
"allowedProjectTypes": ["TENT", "ROOM"]
}
PUT /api/project¶
プロジェクト更新
認証: requireAdmin
3. 企画申請管理¶
GET /api/circle-project-application/list?prefix={prefix}&status={status}¶
申請一覧取得(管理者用)
認証: requireAdminPlus
パラメータ:
prefix: プロジェクト prefixstatus: DRAFT | APPROVED | REJECTED(デフォルト: DRAFT)
レスポンス:
{
"applications": {
"application-group-uuid-1": [
{
"id": "uuid",
"name": "第1希望企画",
"category": "FOOD",
"applicationReason": "理由",
"circle": {...},
"leader": {...}
},
{
"id": "uuid",
"name": "第2希望企画",
"category": "EXHIBITION",
...
}
]
},
"total": 1
}
GET /api/circle-project-application/my?prefix={prefix}¶
自分の団体の申請一覧取得
認証: requireAuth
POST /api/circle-project-application¶
企画申請提出(第 1〜第 5 希望)
認証: requireAuth
リクエストボディ:
{
"parentPrefix": "chibafes2024",
"circleId": "circle-001",
"circleName": "サークル名",
"circleNameKana": "サークルメイ",
"leaderName": "責任者名",
"leaderStudentId": "ABC123",
"leaderTel": "090-1234-5678",
"subLeaderName": "副責任者名",
"subLeaderStudentId": "DEF456",
"subLeaderTel": "090-8765-4321",
"preferences": [
{
"name": "第1希望企画名",
"category": "FOOD",
"areaCode": "T",
"place": "工北エリア",
"reason": "第1希望の理由",
"memo": "メモ"
},
{
"name": "第2希望企画名",
"category": "EXHIBITION",
"areaCode": "S",
"place": "理学部エリア",
"reason": "第2希望の理由"
}
]
}
レスポンス:
{
"applicationGroupId": "uuid",
"projects": [
{
"id": "uuid",
"name": "第1希望企画名",
"status": "DRAFT"
}
]
}
POST /api/circle-project-application/approve¶
申請承認/却下
認証: requireAdminPlus
リクエストボディ:
動作:
approve: 選択した企画を承認(同じ applicationGroupId の他の希望は DRAFT 状態のまま維持)reject: 選択した企画を却下
DELETE /api/circle-project-application?applicationGroupId={id}¶
申請削除(DRAFT 状態のみ)
認証: requireAuth
4. 企画管理¶
GET /api/circle-project?id={id}¶
企画詳細取得
認証: requireAuth
GET /api/circle-project/list¶
企画一覧取得
認証: requireAdminPlus
GET /api/circle-project?prefix={prefix}¶
プロジェクト配下の企画一覧取得
認証: requireAuth
GET /api/circle-project/{id}/schedules¶
企画のスケジュール取得
認証: requireAuth
POST /api/circle-project¶
新規企画作成
認証: requireAdmin
PUT /api/circle-project¶
企画更新
認証: requireAdmin または requireCircleProjectManager
PUT /api/circle-project/{id}/archive¶
企画アーカイブ/復元
認証: requireAdmin
リクエストボディ:
PUT /api/circle-project/bulk-update-categories¶
カテゴリー一括更新
認証: requireAdmin
リクエストボディ:
PUT /api/circle-project/bulk-update-areas¶
エリア一括更新
認証: requireAdmin
PUT /api/circle-project/bulk-update-project-types¶
企画種別一括更新
認証: requireAdmin
POST /api/circle-project/join¶
招待コードで企画参加
認証: requireAuth
リクエストボディ:
5. リソース割り当て(Allocation)¶
GET /api/allocation?id={id}¶
割り当て詳細取得
認証: requireAdminPlus
POST /api/allocation¶
割り当て作成
認証: requireAdmin
リクエストボディ:
{
"parentPrefix": "chibafes2024",
"name": "テント(3m×3m)",
"provider": "レンタル業者A",
"max": 50,
"maxPerOne": 2,
"price": 10000,
"unit": "張",
"category": "ITEM_RENTAL_PRICING",
"tagId": "uuid"
}
PUT /api/allocation¶
割り当て更新
認証: requireAdmin
POST /api/allocation/assign¶
企画への割り当て
認証: requireAdmin
リクエストボディ:
PUT /api/allocation/assign/{id}¶
割り当て量更新
認証: requireAdmin
DELETE /api/allocation/assign/{id}¶
割り当て削除
認証: requireAdmin
POST /api/allocation/bulk-assign¶
一括割り当て
認証: requireAdmin
6. スケジュール管理¶
GET /api/schedule?parentPrefix={prefix}&circleProjectId={id}¶
スケジュール一覧取得
認証: requireAuth
POST /api/schedule¶
スケジュール作成
認証: requireAdmin
リクエストボディ:
{
"parentPrefix": "chibafes2024",
"parentFolderId": "uuid",
"name": "説明会",
"scheduleType": "SCHEDULE",
"startTime": "2024-10-15T14:00:00Z",
"endTime": "2024-10-15T16:00:00Z",
"location": "大講義室",
"description": "企画説明会",
"isPublishToCircle": true,
"isCheckinEnabled": true,
"isAllowSelfCheckin": false,
"isRequireManager": true
}
PUT /api/schedule¶
スケジュール更新
認証: requireAdmin
POST /api/schedule/assign¶
企画へのスケジュール割り当て
認証: requireAdmin
リクエストボディ:
PUT /api/schedule/assign/{id}/checkin¶
チェックイン処理
認証: requireAuth(条件により)
リクエストボディ:
7. スケジュールフォルダ¶
GET /api/schedule/folder?parentPrefix={prefix}¶
フォルダ一覧取得
認証: requireAdminPlus
POST /api/schedule/folder¶
フォルダ作成
認証: requireAdmin
PUT /api/schedule/folder¶
フォルダ更新
認証: requireAdmin
DELETE /api/schedule/folder/{id}¶
フォルダ削除
認証: requireAdmin
8. タグ管理¶
GET /api/tags¶
タグ一覧取得
認証: requireAuth
POST /api/tags¶
タグ作成
認証: requireAdminPlus
リクエストボディ:
POST /api/tags/assign¶
企画へのタグ一括割り当て
認証: requireAdmin
PUT /api/tags/{id}¶
タグ更新
認証: requireAdminPlus
DELETE /api/tags/{id}¶
タグ削除
認証: requireAdminPlus
9. プロジェクトマテリアル¶
GET /api/project-text?circleProjectId={id}&textType={type}¶
テキスト取得
認証: requireAuth
パラメータ:
textType: PRSUMMARY | DESCRIPTION | PRDETAIL | REMARK
POST /api/project-text¶
テキスト作成
認証: requireCircleProjectMember
PUT /api/project-text¶
テキスト更新
認証: requireCircleProjectMember
GET /api/image?cprojectId={id}¶
画像一覧取得
認証: requireAuth
POST /api/image¶
画像アップロード
認証: requireCircleProjectMember
リクエスト: multipart/form-data
DELETE /api/image/{id}¶
画像削除
認証: requireCircleProjectMember
GET /api/sns-data?circleProjectId={id}¶
SNS 情報取得
認証: requireAuth
POST /api/sns-data¶
SNS 情報作成
認証: requireCircleProjectMember
10. 更新リクエスト管理¶
GET /api/project-text-request/list?parentPrefix={prefix}&status={status}¶
更新リクエスト一覧
認証: requireAdminPlus
POST /api/project-text-request¶
更新リクエスト作成
認証: requireCircleProjectMember
POST /api/project-text-request/approve¶
更新リクエスト承認
認証: requireAdminPlus
POST /api/project-text-request/reject¶
更新リクエスト却下
認証: requireAdminPlus
11. サポートケース¶
GET /api/support-case/list?projectPrefix={prefix}&status={status}¶
サポートケース一覧
認証: requireAdminPlus
GET /api/support-case/{id}¶
サポートケース詳細(チャット含む)
認証: requireAuth(作成者または管理者)
POST /api/support-case¶
サポートケース作成
認証: requireAuth
リクエストボディ:
POST /api/support-case/{id}/chat¶
チャットメッセージ追加
認証: requireAuth(作成者または管理者)
PUT /api/support-case/{id}/status¶
ステータス更新
認証: requireAdminPlus
PUT /api/support-case/{id}/assign¶
担当者割り当て
認証: requireAdminPlus
12. 権限申請¶
GET /api/permission-requests/list¶
権限申請一覧
認証: requireAdminPlus
GET /api/permission-requests/my¶
自分の申請一覧
認証: requireAuth
POST /api/permission-requests¶
権限申請作成
認証: requireAuth
リクエストボディ:
POST /api/permission-requests/{id}/approve¶
申請承認
認証: requireAdmin
POST /api/permission-requests/{id}/deny¶
申請却下
認証: requireAdmin
13. リソースレベル権限管理¶
GET /api/resource-permissions?userId={userId}&resourceType={type}&resourceId={id}¶
リソースレベル権限取得
認証: requireAuth(自分の権限取得)または requireResourcePermission(MANAGE_PERMISSIONS)
パラメータ:
userId(optional): ユーザーID(省略時は自分の権限)resourceType(optional): PROJECT | CIRCLE_PROJECTresourceId(optional): リソースID
レスポンス:
{
"permissions": [
{
"id": "uuid",
"userId": "user-uuid",
"resourceType": "PROJECT",
"resourceId": "chibafes2024",
"permissions": ["READ", "WRITE", "APPROVE"],
"grantedBy": "admin-uuid",
"grantedAt": "2024-01-01T00:00:00Z",
"expiresAt": null
}
]
}
POST /api/resource-permissions¶
リソース権限付与
認証: requireResourcePermission(resourceType, resourceId, MANAGE_PERMISSIONS)
リクエストボディ:
{
"userId": "user-uuid",
"resourceType": "PROJECT",
"resourceId": "chibafes2024",
"permissions": ["READ", "WRITE", "APPROVE"]
}
または、ロールテンプレートを使用:
{
"userId": "user-uuid",
"resourceType": "PROJECT",
"resourceId": "chibafes2024",
"roleTemplate": "ProjectManager"
}
PUT /api/resource-permissions/{id}¶
リソース権限更新
認証: requireResourcePermission(resourceType, resourceId, MANAGE_PERMISSIONS)
リクエストボディ:
DELETE /api/resource-permissions/{id}¶
リソース権限削除
認証: requireResourcePermission(resourceType, resourceId, MANAGE_PERMISSIONS)
GET /api/resource-permissions/check?resourceType={type}&resourceId={id}&permissions={perms}¶
権限チェック(開発・デバッグ用)
認証: requireAuth
パラメータ:
resourceType: PROJECT | CIRCLE_PROJECTresourceId: リソースIDpermissions: カンマ区切りの権限リスト(例: READ,WRITE)
レスポンス:
GET /api/resource-role-templates¶
ロールテンプレート一覧取得
認証: requireAuth
パラメータ:
resourceType(optional): PROJECT | CIRCLE_PROJECT
レスポンス:
{
"templates": [
{
"id": "uuid",
"name": "ProjectManager",
"resourceType": "PROJECT",
"permissions": ["READ", "WRITE", "APPROVE", "ALLOCATE_RESOURCES", "VIEW_PRIVATE"],
"description": "プロジェクト管理者用ロール",
"isSystem": true
}
]
}
POST /api/resource-role-templates¶
カスタムロールテンプレート作成
認証: requireAdmin(システム標準ロールの場合)または requireResourcePermission(MANAGE_PERMISSIONS)
リクエストボディ:
{
"name": "CustomRole",
"resourceType": "PROJECT",
"permissions": ["READ", "WRITE"],
"description": "カスタムロール",
"isSystem": false
}
14. 検便管理¶
GET /api/stool-test?projectPrefix={prefix}&circleProjectId={id}¶
検便結果取得
認証: requireAdminPlus
POST /api/stool-test¶
検便結果登録
認証: requireAdminPlus
POST /api/stool-test/bulk-upload¶
検便結果一括登録
認証: requireAdmin
14. 公開 API¶
GET /api/public/circle-project?prefix={prefix}¶
公開企画一覧取得
認証: なし
レスポンス: アーカイブされていない承認済み企画のみ
15. その他¶
GET /api/explore?q={query}&prefix={prefix}¶
企画検索
認証: requireAuth
GET /api/invoice?circleProjectId={id}¶
請求情報取得
認証: requireAdminPlus
POST /api/bulk-invoice¶
請求一括処理
認証: requireAdmin
GET /api/bulk-excel?type={type}&prefix={prefix}¶
Excel 一括エクスポート
認証: requireAdminPlus
パラメータ:
type: allocations | schedules | circle_projects
エラーレスポンス¶
全エンドポイントで統一されたエラーレスポンス形式:
HTTP ステータスコード¶
200 OK: 成功201 Created: 作成成功400 Bad Request: バリデーションエラー401 Unauthorized: 認証エラー403 Forbidden: 権限不足404 Not Found: リソースが存在しない409 Conflict: 重複エラー500 Internal Server Error: サーバーエラー
Webhook 通知¶
プロジェクトのnotificationWebhookが設定されている場合、以下のイベントで通知:
イベントタイプ¶
circle_project_application_created¶
{
"type": "circle_project_application_created",
"applicationGroupId": "uuid",
"circleId": "circle-001",
"circleName": "サークル名",
"preferencesCount": 3,
"timestamp": "2024-01-01T00:00:00Z"
}
circle_project_approved¶
{
"type": "circle_project_approved",
"circleProjectId": "uuid",
"circleProjectName": "企画名",
"timestamp": "2024-01-01T00:00:00Z"
}
データベース設計注意事項¶
BigInt 処理¶
- Prisma の
BigInt型は JSON シリアライズ時に文字列に変換 - FastAPI では
id: intとして扱い、レスポンス時に文字列化
UUID 生成¶
- MySQL 関数:
UUID() - FastAPI:
uuid.uuid4()
タイムゾーン¶
- データベース: UTC 保存
- API: ISO 8601 形式(
2024-01-01T00:00:00Z)
トランザクション¶
- 複数テーブル更新時は必ずトランザクション使用
- 申請承認時の一括更新など
セキュリティ要件¶
- SQL インジェクション対策: ORM パラメータバインディング使用
- XSS 対策: HTML エスケープ(フロントエンド責務)
- CSRF 対策: Bearer Token 認証のため不要
- レート制限: FastAPI ミドルウェアで実装推奨
- CORS: 本番環境では許可オリジン制限
- ログ: 個人情報をログに出力しない
パフォーマンス要件¶
-
キャッシング:
- プロジェクト一覧: 60 秒 TTL
- 公開企画一覧: 300 秒 TTL
-
ページネーション:
- 一覧 API:
limitとoffsetパラメータ実装推奨
- 一覧 API:
-
Eager Loading:
- N+1 問題回避のためリレーション事前ロード
-
インデックス:
CircleProject.parentPrefixCircleProject.statusCircleProject.applicationGroupIdScheduleAssignment.scheduleIdScheduleAssignment.circleProjectId
移行計画¶
Phase 1: コア API¶
- 認証・ユーザー管理
- プロジェクト管理
- 企画管理(基本 CRUD)
Phase 2: 申請フロー¶
- 企画申請機能
- 承認ワークフロー
- 権限申請
Phase 3: リソース管理¶
- Allocation 管理
- スケジュール管理
- チェックイン機能
Phase 4: 補助機能¶
- サポートケース
- マテリアル更新リクエスト
- 検便管理
- Webhook 通知
Phase 5: 最適化¶
- キャッシング実装
- ページネーション
- 全文検索最適化
テスト要件¶
- 単体テスト: 各エンドポイントの正常系・異常系
- 認可テスト: ロールごとのアクセス制御
- 統合テスト: トランザクション動作確認
- 負荷テスト: 同時アクセス性能測定
ドキュメント¶
- OpenAPI 仕様: FastAPI の
/docs(Swagger UI) - ReDoc:
/redoc - スキーマ:
/openapi.json
付録¶
実装時のディレクトリ構成例¶
api/
├── main.py # FastAPIアプリケーションエントリポイント
├── config.py # 環境変数・設定
├── database.py # データベース接続
├── dependencies.py # 認証依存性
├── models/ # SQLAlchemyモデル
│ ├── __init__.py
│ ├── user.py
│ ├── project.py
│ ├── circle_project.py
│ └── ...
├── schemas/ # Pydanticスキーマ
│ ├── __init__.py
│ ├── user.py
│ ├── project.py
│ └── ...
├── routers/ # APIルーター
│ ├── __init__.py
│ ├── auth.py
│ ├── users.py
│ ├── projects.py
│ ├── circle_projects.py
│ ├── applications.py
│ ├── allocations.py
│ ├── schedules.py
│ ├── tags.py
│ ├── support_cases.py
│ └── ...
├── services/ # ビジネスロジック
│ ├── __init__.py
│ ├── auth_service.py
│ ├── application_service.py
│ └── ...
├── utils/ # ユーティリティ
│ ├── __init__.py
│ ├── auth0.py
│ ├── webhook.py
│ └── ...
└── tests/ # テスト
├── __init__.py
├── test_auth.py
└── ...
変更履歴¶
- v1.0 (2025-01-07): 初版作成