🏢 組織サービス
組織サービスは、組織エンティティをCRUD操作で管理するための完全な REST API を提供します。NodeBlocks の関数型合成アプローチで構築され、MongoDB とシームレスに統合します。
🚀 クイックスタート
import express from 'express';
import {middlewares, services, drivers} from '@nodeblocks/backend-sdk';
const {nodeBlocksErrorMiddleware} = middlewares;
const {organizationService} = services;
const {withMongo, createFileStorageDriver} = drivers;
const connectToDatabase = withMongo('mongodb://localhost:27017/?authSource=admin', 'dev', 'user', 'password');
// オプションですが、ロゴ正規化およびアップロードURLには推奨されます:
// GOOGLE_APPLICATION_CREDENTIALS が GCP サービスアカウント JSON を指していることを確認してください。
const fileStorageDriver = createFileStorageDriver(process.env.GCP_PROJECT_ID!, process.env.GCP_BUCKET_NAME!);
express()
.use(
organizationService(
{
...(await connectToDatabase('organizations')),
...(await connectToDatabase('identities')),
...(await connectToDatabase('onetimetokens')),
...(await connectToDatabase('profiles')), // 組織フォロワー機能に必要
...(await connectToDatabase('organizationChangeRequests')), // 変更リクエスト管理では任意
},
{
authSecrets: {
authEncSecret: 'your-encryption-secret',
authSignSecret: 'your-signing-secret',
},
authMode: 'bearer', // または 'cookie'
identity: {
typeIds: {
admin: '100',
guest: '000',
regular: '001',
},
},
organization: {
roles: {
admin: '100',
member: '001',
owner: '010',
},
},
},
{ fileStorageDriver }
)
)
.use(nodeBlocksErrorMiddleware())
.listen(8089, () => console.log('Server running'));
📋 エンドポイント概要
基本CRUD操作
| メソッド | パス | 説明 | 認可 |
|---|---|---|---|
POST | /organizations | 新しい組織を作成 | ベアラートークン必須(管理者のみ) |
GET | /organizations/:organizationId | IDで組織を取得 | ベアラートークン必須(管理者/組織アクセス) |
GET | /organizations | 組織を一覧/フィルタ | ベアラートークン必須(管理者のみ) |
PATCH | /organizations/:organizationId | 組織を更新 | ベアラートークン必須(管理者/所有者アクセス) |
DELETE | /organizations/:organizationId | 組織を削除 | ベアラートークン必須(管理者/所有者アクセス) |
ファイルアップロード操作
| メソッド | パス | 説明 | 認可 |
|---|---|---|---|
GET | /organizations/:organizationId/logo-upload-url | 組織ロゴアップロード用の署名付きURLを取得 | ベアラートークン必須(管理者/所有者アクセス) |
GET | /organizations/:organizationId/certificate-upload-url | 組織証明書アップロード用の署名付きURLを取得 | ベアラートークン必須(管理者/所有者アクセス) |
変更リクエスト操作
| メソッド | パス | 説明 | 認可 |
|---|---|---|---|
POST | /organizations/:organizationId/change-requests | 証明書と資格情報を含む組織変更リクエストを作成 | ベアラートークン必須(管理者/所有者アクセス) |
GET | /organizations/:organizationId/change-requests | 組織変更リクエストをページネーション付きで一覧 | ベアラートークン必須(管理者/所有者アクセス) |
管理操作
| メソッド | パス | 説明 | 認可 |
|---|---|---|---|
PATCH | /admin/organizations/:organizationId/ | 監査ステータスを含む管理者専用フィールドで組織を更新 | ベアラートークン必須(管理者のみ) |
階層操作
| メソッド | パス | 説明 | 認可 |
|---|---|---|---|
GET | /organizations/:organizationId/descendants | 子孫組織を一覧(オプションの深さ制限) | ベアラートークン必須(管理者/所有者アクセス) |
ユーザ管理操作
| メソッド | パス | 説明 | 認可 |
|---|---|---|---|
GET | /organizations/:organizationId/members | 組織のメンバーを一覧 | ベアラートークン必須(管理者/組織アクセス) |
PATCH | /organizations/:organizationId/members | 組織にメンバーを追加/更新 | ベアラートークン必須(管理者/組織アクセス) |
DELETE | /organizations/:organizationId/members/:identityId | 組織からメンバーを削除 | ベアラートークン必須(管理者/組織アクセス) |
GET | /organizations/:organizationId/members/:identityId/role | 組織内のメンバーの役割を取得 | ベアラートークン必須(管理者/組織アクセス) |
GET | /organizations/members/:identityId | メンバーの所属組織を検索 | ベアラートークン必須(管理者/自己アクセス) |
GET | /organizations/:organizationId/members/check-existence | アイデンティティがメンバーかを確認 | ベアラートークン必須(管理者/組織アクセス) |
組織フォロワー操作
| メソッド | パス | 説明 | 認可 |
|---|---|---|---|
GET | /organizations/:organizationId/followers | 組織フォロワーをページネーション付きで取得 | ベアラートークン必須(管理者/所有者アクセス) |
🗄️ エンティティスキーマ
組織エンティティは、自動生成されるベースフィールドと組織固有のデータで構成されます:
{
"id": "string",
"createdAt": "string (datetime)",
"updatedAt": "string (datetime)",
"name": "string",
"description": "string",
"contact_email": "string",
"contact_phone": "string",
"address": "object",
"logo": "object or null",
"members": "array"
}
フィールド詳細
| フィールド | 型 | 自動生成 | 必須 | 説明 |
|---|---|---|---|---|
id | string | ✅ | ✅ | 一意識別子(UUID) |
createdAt | datetime | ✅ | ✅ | 作成日時 |
updatedAt | datetime | ✅ | ✅ | 最終更新日時 |
name | string | ❌ | ✅ | 組織名(最小1文字) |
description | string | ❌ | ✅ | 組織説明 |
contact_email | string | ❌ | ✅ | 連絡先メールアドレス(メール形式) |
contact_phone | string | ❌ | ❌ | 連絡先電話番号 |
address | object | ❌ | ❌ | アドレスオブジェクト(自由形式JSON) |
logo | object or null | ❌ | ❌ | 組織ロゴ。レスポンス: { type, url }; リクエスト: { objectId, type } |
members | array | ❌ | ❌ | 役割付きのアイデンティティ配列({identityId: string, role: string}) |
📝 注意: 自動生成フィールドはサービス側で設定され、作成/更新リクエストに含めないでください。
🔐 認証ヘッダー
すべてのエンドポイントで、次の認証情報を含めてください:
Authorization: Bearer <access_token> // bearer モード(既定)
x-nb-fingerprint: <device_fingerprint>
⚠️ 重要: 認可時にフィンガープリントを指定した場合、認証済みのすべてのリクエストで
x-nb-fingerprintヘッダーが必須です。欠如している場合は 401 Unauthorized が返ります。
authMode: 'cookie' を指定した場合、アクセストークンは Authorization ヘッダーではなく accessToken Cookie から読み取られます。
🔧 APIエンドポイント
1. 組織作成
提供された情報で新しい組織を作成します。
リクエスト:
- メソッド:
POST - パス:
/organizations - ヘッダー:
Content-Type: application/jsonAuthorization: Bearer <token>x-nb-fingerprint: <device-fingerprint>
- 認可: ベアラートークン必須(管理者のみ)
リクエストボディ(トップレベル):
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
organization | object | ✅ | 組織ペイロードオブジェクト(下記参照) |
ownerId | string | ✅ | 組織所有者のアイデンティティID |
parentId | string | ❌ | オプションの親組織ID |
組織オブジェクトフィールド:
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
name | string | ✅ | 組織名(最小1文字) |
description | string | ✅ | 組織説明 |
contact_email | string | ✅ | 連絡先メールアドレス(メール形式) |
branchName | string | ❌ | 組織の支店名 |
contact_phone | string | ❌ | 連絡先電話番号 |
address | object | ❌ | アドレスオブジェクト(自由形式JSON) |
logo | object | null | ❌ | ロゴ参照({ objectId: string, type: string })または null |
certificateImage | object | ❌ | 証明書画像参照({ objectId: string, type: string }) |
certifiedQualifications | array | ❌ | 資格情報オブジェクトの配列({ name: string, status: string, value: string }) |
typeId | string | ❌ | 組織種別 ID |
レスポンスボディ:
| フィールド | 型 | 説明 |
|---|---|---|
id | string | 一意の組織識別子 |
name | string | 組織名 |
description | string | 組織説明 |
contact_email | string | 連絡先メールアドレス |
contact_phone | string | 連絡先電話番号 |
address | object | アドレスオブジェクト(自由形式JSON) |
members | array | アイデンティティ ID と役割を含むオブジェクトの配列: {identityId: string, role: string} |
createdAt | string | 作成日時 |
updatedAt | string | 最終更新日時 |
バリデーション:
- スキーマ検証: 自動強制(トップレベルの
organizationとownerId必須;organization内でname、description、contact_email必須; additionalProperties: false) - ルートバリデーション:
- 認証済みリクエスト(ベアラートークン)が必要
- 管理者ロール必須
リクエスト例:
curl -X POST {{host}}/organizations \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access-token>" \
-d '{
"organization": {
"name": "ACME Corp",
"description": "Leading provider of rocket skates",
"contact_email": "info@acme.test",
"contact_phone": "+1-202-555-0199",
"address": {
"street": "1 Road Runner Way",
"city": "Desert",
"country": "US"
}
},
"ownerId": "identity-123",
"parentId": "org-parent-001"
}'
成功レスポンス:
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2",
"name": "ACME Corp",
"description": "Leading provider of rocket skates",
"contact_email": "info@acme.test",
"contact_phone": "+1-202-555-0199",
"address": {
"street": "1 Road Runner Way",
"city": "Desert",
"country": "US"
},
"members": [
{
"identityId": "owner-id",
"role": "owner"
}
],
"createdAt": "2024-05-28T09:41:22.552Z",
"updatedAt": "2024-05-28T09:41:22.552Z"
}
エラーレスポンス:
リクエストボディに必須フィールドがない場合:
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": {
"message": "Validation Error",
"data": [
"request body must have required property 'name'",
"request body must have required property 'description'",
"request body must have required property 'contact_email'",
"request body must have required property 'ownerId'"
]
}
}
認可トークンが提供されていない場合:
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{
"error": {
"message": "token could not be verified"
}
}
データベース挿入操作が挿入されたIDを返せなかった場合:
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": {
"message": "Failed to create organization"
}
}
予期しないエラーが発生した場合(DB接続問題など):
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
{
"error": {
"message": "Failed to create organization"
}
}
2. IDで組織取得
一意のIDで特定の組織を取得します。
リクエスト:
- メソッド:
GET - パス:
/organizations/:organizationId - ヘッダー:
Authorization: Bearer <access-token> - 認可: ベアラートークン必須(管理者/組織アクセス)
URL パラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
organizationId | string | ✅ | 一意の組織識別子 |
レスポンスボディ:
| フィールド | 型 | 説明 |
|---|---|---|
id | string | 一意の組織識別子 |
name | string | 組織名 |
description | string | 組織説明 |
contact_email | string | 連絡先メールアドレス |
contact_phone | string | 連絡先電話番号 |
address | object | アドレスオブジェクト(自由形式JSON) |
users | array | ユーザーIDと役割を含むオブジェクトの配列: {id: string, role: string} |
createdAt | string | 作成日時 |
updatedAt | string | 最終更新日時 |
バリデーション:
- スキーマ検証: なし
- ルートバリデーション:
- 認証済みリクエスト(ベアラー)必須
- 管理者ロールまたは組織メンバーシップ必須(所有者/管理者/メンバー)
リクエスト例:
curl {{host}}/organizations/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2
成功レスポンス:
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2",
"name": "ACME Corp",
"description": "Leading provider of rocket skates",
"contact_email": "info@acme.test",
"contact_phone": "+1-202-555-0199",
"address": {
"street": "1 Road Runner Way",
"city": "Desert",
"country": "US"
},
"users": [
{
"id": "owner-id",
"role": "owner"
}
],
"createdAt": "2024-05-28T09:41:22.552Z",
"updatedAt": "2024-05-28T09:41:22.552Z"
}
エラーレスポンス:
指定IDの組織が存在しない場合:
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error": {
"message": "Organization not found"
}
}
予期しないエラーが発生した場合(DB接続問題など):
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
{
"error": {
"message": "Failed to get organization"
}
}
3. 組織一覧
フィルタやページングを指定して組織の一覧を取得します。
リクエスト:
- メソッド:
GET - パス:
/organizations - 認可: ベアラートークン必須(管理者のみ)
クエリパラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
name | string | ❌ | 組織名でフィルタ(最小1文字) |
description | string | ❌ | 組織説明でフィルタ |
contact_email | string | ❌ | 連絡先メールアドレスでフィルタ(メール形式) |
contact_phone | string | ❌ | 連絡先電話番号でフィルタ |
page | number | ❌ | ページ番号 |
limit | number | ❌ | 1ページあたりの件数 |
レスポンスボディ:
| フィールド | 型 | 説明 |
|---|---|---|
id | string | 一意の組織識別子 |
name | string | 組織名 |
description | string | 組織説明 |
contact_email | string | 連絡先メールアドレス |
contact_phone | string | 連絡先電話番号 |
address | object | アドレスオブジェクト(自由形式JSON) |
users | array | ユーザーIDと役割を含むオブジェクトの配列: {id: string, role: string} |
createdAt | string | 作成日時 |
updatedAt | string | 最終更新日時 |
バリデーション:
- スキーマ検証: name(最小長1)、contact_email(メール形式)、contact_phone(string)、description(string)、ページングパラメータ(最小/最大制約のある整数)のクエリ検証
- ルートバリデーション:
- 認証済みリクエスト(ベアラー)必須
- 管理者ロール必須
リクエスト例:
全件取得:
curl {{host}}/organizations
組織名でフィルタ:
curl "{{host}}/organizations?name=ACME Corp"
連絡先メールアドレスでフィルタ:
curl "{{host}}/organizations?contact_email=info@acme.test"
組織説明でフィルタ:
curl "{{host}}/organizations?description=rocket skates"
連絡先電話番号でフィルタ:
curl "{{host}}/organizations?contact_phone=+1-202-555-0199"
複合フィルタ:
curl "{{host}}/organizations?name=ACME&contact_email=info@acme.test&page=1&limit=20"
成功レスポンス:
HTTP/1.1 200 OK
Content-Type: application/json
[
{
"id": "7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2",
"name": "ACME Corp",
"description": "Leading provider of rocket skates",
"contact_email": "info@acme.test",
"contact_phone": "+1-202-555-0199",
"address": {
"street": "1 Road Runner Way",
"city": "Desert",
"country": "US"
},
"users": [
{
"id": "owner-id",
"role": "owner"
}
],
"createdAt": "2024-05-28T09:41:22.552Z",
"updatedAt": "2024-05-28T09:41:22.552Z"
},
{
"id": "8fec096b-1bc7-5bfe-c827-3600e8fe2790",
"name": "Wayne Enterprises",
"description": "Gotham's premier technology company",
"contact_email": "contact@wayneenterprises.com",
"users": [
{
"id": "owner-id",
"role": "owner"
}
],
"createdAt": "2024-05-29T10:15:33.441Z",
"updatedAt": "2024-05-29T10:15:33.441Z"
}
]
エラーレスポンス:
予期しないエラーが発生した場合(DB接続問題、フィルタ構文不正など):
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
{
"error": {
"message": "Failed to find organizations"
}
}
4. 組織更新
部分更新で既存の組織を更新します。
リクエスト:
- メソッド:
PATCH - パス:
/organizations/:organizationId - ヘッダー:
Content-Type: application/json - 認可: ベアラートークン必須(管理者/所有者アクセス)
URL パラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
organizationId | string | ✅ | 一意の組織識別子 |
レスポンスボディ:
| フィールド | 型 | 説明 |
|---|---|---|
id | string | 一意の組織識別子 |
name | string | 更新後の組織名 |
description | string | 更新後の組織説明 |
contact_email | string | 更新後の連絡先メールアドレス |
contact_phone | string | 更新後の連絡先電話番号 |
address | object | 更新後のアドレスオブジェクト(自由形式JSON) |
createdAt | string | 作成日時 |
updatedAt | string | 最終更新日時 |
バリデーション:
- スキーマ検証: 自動強制(部分更新、全フィールド任意)
- ルートバリデーション:
- 認証済みリクエスト(ベアラー)必須
- 管理者ロールまたは組織所有者ロール必須
リクエスト例:
curl -X PATCH {{host}}/organizations/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2 \
-H "Content-Type: application/json" \
-d '{"description": "Updated description for ACME Corp"}'
成功レスポンス:
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2",
"name": "ACME Corp",
"description": "Updated description for ACME Corp",
"contact_email": "info@acme.test",
"contact_phone": "+1-202-555-0199",
"address": {
"street": "1 Road Runner Way",
"city": "Desert",
"country": "US"
},
"users": [
{
"id": "owner-id",
"role": "owner"
}
],
"createdAt": "2024-05-28T09:41:22.552Z",
"updatedAt": "2024-05-28T14:22:15.789Z"
}
エラーレスポンス:
リクエストボディがないまたは空の場合:
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": {
"message": "Request body is required"
}
}
指定IDの組織が存在しない場合:
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error": {
"message": "Organization not found"
}
}
更新操作でデータが変更されない場合(変更なし):
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": {
"message": "Failed to update organization"
}
}
予期しないエラーが発生した場合(DB接続問題など):
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
{
"error": {
"message": "Failed to update organization"
}
}
5. 組織削除
システムから組織を完全に削除します。
リクエスト:
- メソッド:
DELETE - パス:
/organizations/:organizationId - 認可: ベアラートークン必須(管理者/所有者アクセス)
URL パラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
organizationId | string | ✅ | 一意の組織識別子 |
レスポンスボディ:
| フィールド | 型 | 説明 |
|---|---|---|
| なし | - | 成功時はレスポンスボディなし |
バリデーション:
- スキーマ検証: なし
- ルートバリデーション:
- 認証済みリクエスト(ベアラー)必須
- 管理者ロールまたは組織所有者ロール必須
リクエスト例:
curl -X DELETE {{host}}/organizations/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2
成功レスポンス:
HTTP/1.1 204 No Content
エラーレスポンス:
指定IDの組織が存在しない場合:
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error": {
"message": "Organization not found"
}
}
予期しないエラーが発生した場合(DB接続問題など):
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
{
"error": {
"message": "Failed to delete organization"
}
}
👥 ユーザ管理エンドポイント
6. 組織メンバーの一覧
組織に関連付けられたユーザーの一覧を取得します。
リクエスト:
- メソッド:
GET - パス:
/organizations/:organizationId/members - ヘッダー:
Authorization: Bearer <access-token> - 認可: ベアラートークン必須(管理者/組織アクセス)
URL パラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
organizationId | string | ✅ | 一意の組織識別子 |
バリデーション:
- スキーマ検証: なし(GET リクエスト)
- ルートバリデーション:
- 認証済みリクエスト(ベアラー)必須
- 管理者ロールまたは組織所有者/管理者ロール必須
リクエスト例:
curl {{host}}/organizations/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2/members
成功レスポンス:
HTTP/1.1 200 OK
Content-Type: application/json
{
"count": 2,
"total": 2,
"value": [
{
"id": "identity-123",
"role": "admin"
},
{
"id": "392157b1-dc7a-4935-a6f9-a2d333b910ea",
"role": "owner"
}
]
}
7. 組織メンバーの追加/更新
組織に新しいユーザーを追加するか、既存のユーザーロールを更新します。upsertロジックを使用 - ユーザーが存在する場合ロールを更新、存在しない場合は追加します。
リクエスト:
- メソッド:
PATCH - パス:
/organizations/:organizationId/members - ヘッダー:
Content-Type: application/json,Authorization: Bearer <access-token> - 認可: ベアラートークン必須(管理者/組織アクセス)
URL パラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
organizationId | string | ✅ | 一意の組織識別子 |
リクエストボディ: 追加/更新するメンバーオブジェクトの配列:
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
identityId | string | ✅ | アイデンティティ識別子 |
role | string | ✅ | 組織内のメンバーロール |
バリデーション:
- スキーマ検証: 自動強制(必須のidおよびroleフィールドを含む配列)
- ルートバリデーション:
- 認証済みリクエスト(ベアラー)必須
- 管理者ロールまたは組織所有者/管理者ロール必須
リクエスト例:
curl -X PATCH {{host}}/organizations/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2/members \
-H "Content-Type: application/json" \
-d '[
{"identityId": "user123", "role": "admin"},
{"identityId": "user456", "role": "member"}
]'
成功レスポンス:
HTTP/1.1 204 No Content
エラーレスポンス:
リクエストボディがないまたは空の場合:
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": {
"message": "Request body non-empty array required"
}
}
組織が存在しない場合:
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error": {
"message": "Organization not found"
}
}
データベース操作が失敗した場合:
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
{
"error": {
"message": "Failed to upsert organization users"
}
}
更新後に組織所有者が 1 人も残らない場合:
HTTP/1.1 409 Conflict
Content-Type: application/json
{"error":{"message":"There must be at least one owner remaining in the organization"}}
8. 組織からのメンバー削除
組織から特定のユーザーを削除します。
リクエスト:
- メソッド:
DELETE - パス:
/organizations/:organizationId/members/:identityId - ヘッダー:
Authorization: Bearer <access-token> - 認可: ベアラートークン必須(管理者/組織アクセス)
URL パラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
organizationId | string | ✅ | 一意の組織識別子 |
identityId | string | ✅ | 一意のアイデンティティ識別子 |
バリデーション:
- スキーマ検証: なし(DELETE リクエスト)
- ルートバリデーション:
- 認証済みリクエスト(ベアラー)必須
- 管理者ロールまたは組織所有者/管理者ロール必須
リクエスト例:
curl -X DELETE {{host}}/organizations/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2/members/identity-123
成功レスポンス:
HTTP/1.1 204 No Content
エラーレスポンス:
組織が存在しない場合:
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error": {
"message": "Organization not found"
}
}
ユーザーが組織にいない場合:
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": {
"message": "Failed to remove user from organization"
}
}
データベース操作が失敗した場合:
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
{
"error": {
"message": "Failed to delete organization user"
}
}
削除後に組織所有者が 1 人も残らない場合:
HTTP/1.1 409 Conflict
Content-Type: application/json
{"error":{"message":"There must be at least one owner remaining in the organization"}}
9. 組織内のメンバー役割取得
組織内の特定のユーザーの役割を取得します。
リクエスト:
- メソッド:
GET - パス:
/organizations/:organizationId/members/:identityId/role - ヘッダー:
Authorization: Bearer <access-token> - 認可: ベアラートークン必須(管理者/組織アクセス)
URL パラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
organizationId | string | ✅ | 一意の組織識別子 |
identityId | string | ✅ | 一意のアイデンティティ識別子 |
バリデーション:
- スキーマ検証: パスパラメータ検証(organizationId、identityId必須)
- ルートバリデーション:
- 認証済みリクエスト(ベアラー)必須
- 管理者ロールまたは組織所有者/管理者ロール必須
リクエスト例:
curl {{host}}/organizations/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2/members/identity-123/role
成功レスポンス:
HTTP/1.1 200 OK
Content-Type: application/json
{
"inheritedFrom": "7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2" ,
"role": "owner"
}
エラーレスポンス:
組織またはユーザーが存在しない場合:
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error": {
"message": "Organization not found"
}
}
データベース操作が失敗した場合:
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
{
"error": {
"message": "Failed to get organization user role"
}
}
10. 組織内のメンバー存在確認
組織内に特定のユーザーが存在するかどうかを確認します。
リクエスト:
- メソッド:
GET - パス:
/organizations/:organizationId/members/check-existence - ヘッダー:
Authorization: Bearer <access-token> - 認可: ベアラートークン必須(管理者/組織アクセス)
URL パラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
organizationId | string | ✅ | 一意の組織識別子 |
クエリパラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
identityId | string | ✅ | 確認する一意のアイデンティティ識別子 |
バリデーション:
- スキーマ検証: なし(GET リクエスト)
- ルートバリデーション:
- 認証済みリクエスト(ベアラー)必須
- 管理者ロールまたは組織所有者/管理者ロール必須
リクエスト例:
curl "{{host}}/organizations/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2/members/check-existence?identityId=identity-123"
成功レスポンス:
HTTP/1.1 200 OK
Content-Type: application/json
{
"isUserInOrganization": true
}
エラーレスポンス:
組織が存在しない場合:
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error": {
"message": "Organization not found"
}
}
データベース操作が失敗した場合:
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
{
"error": {
"message": "Failed to check organization user existence"
}
}
11. メンバーの所属組織検索
特定のアイデンティティが所属するすべての組織を取得します。オプションで要求された場合、継承された役割も含みます。
リクエスト:
- メソッド:
GET - パス:
/organizations/members/:identityId - ヘッダー:
Authorization: Bearer <access-token> - 認可: ベアラートークン必須(管理者/自己アクセス)
URL パラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
identityId | string | ✅ | 一意のアイデンティティ識別子 |
クエリパラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
roles | string | ❌ | オプションのカンマ区切り役割フィルタ(例: owner,admin) |
includeInherited | boolean | ❌ | 子孫組織からの継承された役割を含む |
バリデーション:
- スキーマ検証: パスパラメータ検証(identityId必須)とオプションのクエリ検証(rolesはstring; includeInheritedはboolean)
- ルートバリデーション:
- 認証済みリクエスト(ベアラー)必須
- 管理者ロールまたは自己必須
リクエスト例:
curl {{host}}/organizations/members/identity-123
成功レスポンス:
[
{
"member": { "inheritedFrom": null, "role": "owner" },
"organization": {
"id": "org1",
"name": "ACME Corp",
"ancestors": [],
"members": [{ "identityId": "identity-123", "role": "owner" }]
}
},
{
"member": { "inheritedFrom": "org1", "role": "owner" },
"organization": {
"id": "org2",
"ancestors": ["org1"],
"members": [{ "identityId": "identity-123", "role": "member" }]
}
}
]
ユーザーが存在しない場合:
HTTP/1.1 200 OK
Content-Type: application/json
{
"count": 0,
"total": 0,
"value": []
}
12. 組織ロゴアップロードURL取得
組織ロゴ画像を安全にアップロードするための署名付きURLを生成します。オブジェクトIDと一時的な署名付きURLを返します。
リクエスト:
- メソッド:
GET - パス:
/organizations/:organizationId/logo-upload-url - ヘッダー:
Authorization: Bearer <token> - 認可: ベアラートークン必須(管理者/所有者アクセス)
URL パラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
organizationId | string | ✅ | 対象組織ID |
クエリパラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
contentType | string | ✅ | 画像MIMEタイプ(例: image/png) |
contentLength | number | ✅ | ファイルサイズ(バイト単位、最大10MB) |
レスポンスボディ:
| フィールド | 型 | 説明 |
|---|---|---|
objectId | string | ロゴ用の生成されたストレージオブジェクトID |
url | string | ファイルをアップロードするための署名付きURL |
バリデーション:
- スキーマ検証: 画像アップロードスキーマを使用(コンテンツタイプとサイズ制約)
- ルートバリデーション:
- 認証済みリクエスト(ベアラー)必須
- 管理者ロールまたは組織所有者ロール必須
リクエスト例:
curl "{{host}}/organizations/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2/logo-upload-url?contentType=image/png&contentLength=1048576" \
-H "Authorization: Bearer <access-token>"
成功レスポンス:
{
"objectId": "7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2",
"url": "https://storage.googleapis.com/bucket/logos/...&X-Goog-Expires=900&X-Goog-Signature=..."
}
17. 子孫組織の一覧
指定された組織の子孫組織をすべて取得します。オプションで深さ制限を指定できます。
リクエスト:
- メソッド:
GET - パス:
/organizations/:organizationId/descendants - ヘッダー:
Authorization: Bearer <access-token> - 認可: ベアラートークン必須(管理者/所有者アクセス)
URL パラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
organizationId | string | ✅ | 親組織識別子 |
クエリパラメータ:
| パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
depth | number (>=1) | ❌ | 階層深さで子孫を制限 |
バリデーション:
- スキーマ検証: パスパラメータ検証(organizationId必須); depthは提供された場合正の数である必要があります
- ルートバリデーション:
- 認証済みリクエスト(ベアラー)必須
- 管理者ロールまたは組織所有者/管理者ロール必須
リクエスト例:
curl "{{host}}/organizations/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2/descendants?depth=2" \
-H "Authorization: Bearer <access-token>"
成功レスポンス:
[
{
"id": "9044d797-384e-4c60-a3b6-1d900ffd8be8",
"name": "ACME Corp",
"description": "Leading provider of rocket skates",
"contact_email": "info@acme.test",
"createdAt": "2025-08-25T07:42:18.643Z",
"updatedAt": "2025-08-25T07:42:18.643Z"
}
]
13. 組織証明書アップロード URL の取得
GET /organizations/:organizationId/certificate-upload-url は、組織証明書をアップロードするための署名付き URL を返します。プラットフォーム管理者または組織所有者が実行できます。fileStorageDriver の設定が必要です。
リクエスト: GET /organizations/:organizationId/certificate-upload-url。bearer モードでは Authorization: Bearer <token>、cookie モードでは accessToken Cookie を使用します。
| URL パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
organizationId | string | ✅ | 対象組織の ID |
| クエリパラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
contentType | string | ✅ | 証明書の MIME タイプ(application/pdf、image/gif、image/jpeg、image/png) |
contentLength | number | ✅ | ファイルサイズ(最大 10 MB) |
| レスポンスフィールド | 型 | 説明 |
|---|---|---|
objectId | string | 証明書用に生成されたストレージオブジェクト ID |
url | string | ファイルをアップロードする署名付き URL |
スキーマはコンテンツタイプとサイズ制約を検証します。管理者ロールまたは組織所有者ロールが必要です。
curl "{{host}}/organizations/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2/certificate-upload-url?contentType=application/pdf&contentLength=1048576" \
-H "Authorization: Bearer <access-token>"
{
"objectId": "7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2",
"url": "https://storage.googleapis.com/bucket/certificates/...&X-Goog-Expires=900&X-Goog-Signature=..."
}
14. 組織変更リクエストの作成
POST /organizations/:organizationId/change-requests は証明書および資格情報を含む変更リクエストを作成します。プラットフォーム管理者または組織所有者が利用できます。
リクエスト: POST /organizations/:organizationId/change-requests。Content-Type: application/json と認証情報が必要です。
| URL パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
organizationId | string | ✅ | 組織識別子 |
| リクエストフィールド | 型 | 必須 | 説明 |
|---|---|---|---|
name | string | ❌ | 組織名(最小 1 文字) |
branchName | string | ❌ | 組織の支店名 |
addressLine1 | string | ❌ | 住所 1 行目 |
addressLine2 | string | ❌ | 住所 2 行目 |
addressLine3 | string | ❌ | 住所 3 行目 |
postalCode | string | ❌ | 郵便番号 |
typeId | string | ❌ | 組織種別 ID |
certificateImage | object | ❌ | 証明書画像参照({ objectId: string, type: string }) |
certifiedQualifications | array | ❌ | 資格情報の配列 |
少なくとも 1 つのフィールドを指定してください。認証済みの管理者または組織所有者のみが実行できます。成功時は 204 No Content を返します。
curl -X POST "{{host}}/organizations/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2/change-requests" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access-token>" \
-d '{"name":"Updated Organization Name","certificateImage":{"objectId":"cert-123","type":"application/pdf"}}'
HTTP/1.1 204 No Content
15. 組織変更リクエストの一覧
GET /organizations/:organizationId/change-requests は、page と limit によるページネーションを含め、その組織の変更リクエストを返します。プラットフォーム管理者または組織所有者が利用できます。
| URL パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
organizationId | string | ✅ | 組織識別子 |
| クエリパラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
page | number | ❌ | ページ番号(1~1000) |
limit | number | ❌ | 1ページあたりの件数(1~50) |
証明書画像を含む変更リクエストでは、certificateImage と certificateImageUrl が返されます。レスポンスは変更リクエストの data 配列とページネーションの metadata を持ちます。
{
"data": [{
"id": "string",
"organizationId": "string",
"identityId": "string",
"name": "string",
"certificateImage": {"objectId": "string", "type": "string"},
"certificateImageUrl": "string",
"certifiedQualifications": [{"name": "string", "status": "string", "value": "string"}],
"createdAt": "string",
"updatedAt": "string"
}],
"metadata": {"pagination": {"page": number, "limit": number, "total": number, "totalPages": number, "hasNext": boolean, "hasPrev": boolean}}
}
スキーマはパスおよびページネーションクエリを検証します。認証済みの管理者または組織所有者のみが実行できます。
curl "{{host}}/organizations/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2/change-requests?page=1&limit=20" \
-H "Authorization: Bearer <access-token>"
HTTP/1.1 200 OK
Content-Type: application/json
{"data":[{"id":"change-request-123","organizationId":"7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2","identityId":"identity-456","name":"Updated Organization Name","certificateImage":{"objectId":"cert-123","type":"application/pdf"},"certificateImageUrl":"https://storage.googleapis.com/...","createdAt":"2025-01-15T10:30:00.000Z","updatedAt":"2025-01-15T10:30:00.000Z"}],"metadata":{"pagination":{"page":1,"limit":20,"total":1,"totalPages":1,"hasNext":false,"hasPrev":false}}}
16. 管理者による組織更新
PATCH /admin/organizations/:organizationId/ は、監査ステータスなどの管理者専用フィールドを更新します。プラットフォーム管理者のみが実行できます。
| URL パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
organizationId | string | ✅ | 一意の組織識別子 |
| 更新可能なフィールド | 型 | 必須 | 説明 |
|---|---|---|---|
name | string | ❌ | 組織名 |
branchName | string | ❌ | 組織の支店名 |
description | string | ❌ | 組織の説明 |
contact_email | string | ❌ | 連絡先メールアドレス |
contact_phone | string | ❌ | 連絡先電話番号 |
address | object | ❌ | 住所オブジェクト |
typeId | string | ❌ | 組織種別 ID |
logo | object または null | ❌ | ロゴ参照または null |
certificateImage | object | ❌ | 証明書画像参照 |
certifiedQualifications | array | ❌ | 資格情報の配列 |
auditStatus | string | ❌ | 監査ステータス |
拡張管理者スキーマがすべてのフィールドと auditStatus を検証します。認証済みのプラットフォーム管理者のみが実行できます。
| レスポンスフィールド | 型 | 説明 |
|---|---|---|
id | string | 一意の組織識別子 |
name | string | 更新後の組織名 |
description | string | 更新後の組織説明 |
contact_email | string | 更新後の連絡先メールアドレス |
contact_phone | string | 更新後の連絡先電話番号 |
address | object | 更新後の住所オブジェクト |
logo | object または null | 署名付き URL を含む正規化済みロゴ、または null |
certificateImage | object または null | 更新後の証明書画像参照 |
certificateImageUrl | string | 証明書画像がある場合の更新後の署名付き URL |
certifiedQualifications | array | 更新後の資格情報 |
auditStatus | string | 更新後の監査ステータス |
createdAt | string | 作成日時 |
updatedAt | string | 最終更新日時 |
組織に証明書画像がある場合にのみ、certificateImage と certificateImageUrl が含まれます。
curl -X PATCH "{{host}}/admin/organizations/7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2/" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access-token>" \
-d '{"auditStatus":"approved","certificateImage":{"objectId":"cert-123","type":"application/pdf"}}'
HTTP/1.1 200 OK
Content-Type: application/json
{"id":"7edfb95f-0ab6-4adc-a6e1-2a86a2f1e6d2","name":"ACME Corp","description":"Leading provider of rocket skates","contact_email":"info@acme.test","auditStatus":"approved","certificateImage":{"objectId":"cert-123","type":"application/pdf"},"certificateImageUrl":"https://storage.googleapis.com/...","createdAt":"2024-05-28T09:41:22.552Z","updatedAt":"2025-01-15T14:22:15.789Z"}
18. 組織フォロワーの取得
GET /organizations/:organizationId/followers は、組織をフォローしているプロフィールをページネーション付きで返します。profiles データストアが必要で、プラットフォーム管理者または組織所有者が利用できます。
| URL パラメータ | 型 | 必須 | 説明 |
|---|---|---|---|
organizationId | string | ✅ | フォロワーを取得する組織 ID |
| クエリパラメータ | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
page | number | ❌ | 1 | ページ番号(1~1000) |
limit | number | ❌ | 20 | 1ページあたりの結果数(1~50) |
レスポンス構造:
{"data":[{"id":"string","name":"string","avatar":{"url":"string","type":"string"}}],"metadata":{"pagination":{"page":number,"limit":number,"total":number,"totalPages":number,"hasNext":boolean,"hasPrev":boolean}}}
| フォロワーフィールド | 型 | 説明 |
|---|---|---|
id | string | フォロワーの識別子 |
name | string | フォロワーの表示名 |
avatar は任意で、アバターがないフォロワーでは省略されます。組織 ID をスキーマで検証し、認証済みの管理者または組織所有者であること、および組織の存在が必要です。データストアまたはファイルストレージの失敗は 500、組織がない場合は 404 を返します。
curl -X GET "{{host}}/organizations/org-abc-123/followers?page=1&limit=20" \
-H "Authorization: Bearer <access-token>"
HTTP/1.1 200 OK
Content-Type: application/json
{"data":[{"id":"user-456","name":"John Doe","avatar":{"url":"https://storage.example.com/avatars/avatar123.png","type":"image/png"}},{"id":"user-789","name":"Jane Smith","avatar":{"url":"https://storage.example.com/avatars/avatar456.jpg","type":"image/jpeg"}}],"metadata":{"pagination":{"page":1,"limit":20,"total":50,"totalPages":3,"hasNext":true,"hasPrev":false}}}
HTTP/1.1 404 Not Found
Content-Type: application/json
{"error":{"message":"Organization not found"}}
ユースケース: 組織のフォロワー数と成長の分析、購読者の確認、フォロワー向けコンテンツ配信、組織中心のコミュニティ機能に使用できます。ページネーション、アバター URL の正規化、柔軟なページ指定、$elemMatch を使用する最適化済み MongoDB クエリを提供します。
⚙️ 設定オプション
サービス設定
interface OrganizationServiceConfiguration {
authSecrets: {
authEncSecret: string; // JWT 暗号化シークレット
authSignSecret: string; // JWT 署名シークレット
};
authMode?: 'bearer' | 'cookie'; // 未指定時は bearer
identity?: {
typeIds?: {
admin: string; // 管理者ユーザー種別識別子
guest: string; // ゲストユーザー種別識別子
regular: string; // 一般ユーザー種別識別子
};
};
organization?: {
roles?: {
admin: string; // 管理者役割識別子
member: string; // メンバー役割識別子
owner: string; // 所有者役割識別子
};
};
}
データストア
| コレクション | 必須 | 説明 |
|---|---|---|
identities | ✅ | アイデンティティの検索および認証コンテキスト |
organizations | ✅ | 組織ドキュメントおよびメンバーシップ |
onetimetokens | 変更リクエスト時 | 組織変更リクエストのワークフローで使用するワンタイムトークン |
profiles | ✅ | 組織フォロワーのプロフィールデータ |
organizationChangeRequests | ❌ | 組織変更リクエストのドキュメント |
設定詳細
組織サービスの設定は、セキュリティ、ユーザー種別管理、組織役割管理の論理グループに整理されています。
🔐 セキュリティ設定
authSecrets - JWT トークンのセキュリティシークレット
- 型:
{ authEncSecret: string; authSignSecret: string } - 説明: JWT の暗号化および署名に使用する秘密鍵(トークン検証に使用)
- 必須: 本番環境では必須
- 子プロパティ:
authEncSecret: JWT ペイロード暗号化の秘密鍵authSignSecret: JWT 署名検証の秘密鍵
👥 ユーザー種別設定
user.typeIds - ユーザー種別識別子の設定
- 型:
{ admin?: string; guest?: string; user?: string } - 説明: ロールベースアクセス制御のためのカスタムユーザー種別識別子
- デフォルト:
undefined(デフォルトの種別検証を使用) - 子プロパティ:
admin: 管理者ユーザー種別の識別子- 型:
string - 説明: 管理者ユーザーのカスタム識別子
- 利用例: 管理操作のロールベースアクセス制御
- 例:
"admin","administrator","superuser"
- 型:
guest: ゲストユーザー種別の識別子- 型:
string - 説明: ゲストユーザーのカスタム識別子
- 利用例: 未認証/一時ユーザーの限定的アクセス
- 例:
"guest","visitor","anonymous"
- 型:
user: 一般ユーザー種別の識別子- 型:
string - 説明: 一般ユーザーのカスタム識別子
- 利用例: 標準的なユーザー権限
- 例:
"user","member","customer"
- 型:
🏢 組織役割設定
organization.roles - 組織役割識別子の設定
- 型:
{ admin?: string; member?: string; owner?: string } - 説明: 組織内ユーザー管理のためのカスタム組織役割識別子
- デフォルト:
undefined(デフォルトの役割検証を使用) - 子プロパティ:
admin: 管理者役割識別子- 型:
string - 説明: 組織管理者役割のカスタム識別子
- 利用例: 組織内の管理権限
- 例:
"admin","administrator","manager"
- 型:
member: メンバー役割識別子- 型:
string - 説明: 組織メンバー役割のカスタム識別子
- 利用例: 組織内の標準的なメンバー権限
- 例:
"member","user","employee"
- 型:
owner: 所有者役割識別子- 型:
string - 説明: 組織所有者役割のカスタム識別子
- 利用例: 組織内の完全制御権限
- 例:
"owner","founder","creator"
- 型:
設定例
const organizationConfig = {
authSecrets: {
authEncSecret: process.env.AUTH_ENC_SECRET || 'your-enc-secret',
authSignSecret: process.env.AUTH_SIGN_SECRET || 'your-sign-secret'
},
user: {
typeIds: {
admin: '100',
guest: '000',
user: '001'
}
},
organization: {
roles: {
admin: '100',
member: '001',
owner: '010'
}
}
};
🚨 エラーハンドリング
組織サービスのエラーは、適切なHTTPステータスコードとJSON形式で返されます:
代表的なエラーコード
| ステータス | エラーメッセージ | 説明 |
|---|---|---|
| 400 | Validation Error | リクエストボディ形式が無効または必須フィールドがない |
| 400 | Request body is required | PATCH操作のリクエストボディがない |
| 400 | Request body non-empty array required | ユーザー管理操作の配列がないまたは空 |
| 400 | Failed to create organization | データベース挿入操作が挿入されたIDを返せなかった |
| 400 | Failed to update organization | 更新操作でデータが変更されない(変更なし) |
| 400 | Failed to remove user from organization | ユーザーが組織にいないまたは削除が失敗した |
| 401 | token could not be verified | 認可トークンがない/無効 |
| 403 | User is not authorized to access this resource | 必要な権限がない(管理者/組織アクセス) |
| 404 | Organization not found | 要求された操作の対象組織が存在しない |
| 500 | Failed to create organization | 作成中のDB接続問題/予期せぬ失敗 |
| 500 | Failed to get organization | 取得中のDB接続問題/予期せぬ失敗 |
| 500 | Failed to find organizations | 一覧取得中のDB接続問題/フィルタ構文不正/予期せぬ失敗 |
| 500 | Failed to update organization | 更新中のDB接続問題/予期せぬ失敗 |
| 500 | Failed to delete organization | 削除中のDB接続問題/予期せぬ失敗 |
| 500 | Failed to upsert organization users | ユーザー管理中のDB接続問題/予期せぬ失敗 |
| 500 | Failed to delete organization user | ユーザー削除中のDB接続問題/予期せぬ失敗 |
| 500 | Failed to get organization user role | 役割取得中のDB接続問題/予期せぬ失敗 |
| 500 | Failed to check organization user existence | 存在確認中のDB接続問題/予期せぬ失敗 |
| 500 | Cannot read properties of undefined (reading 'organizations') | ユーザー組織検索エンドポイントのハンドラー実装バグ |
エラーレスポンス形式
{
"error": {
"message": "Error message description",
"data": ["Additional error details"]
}
}
検証エラーには追加の詳細が含まれます:
{
"error": {
"message": "Validation Error",
"data": [
"request body must have required property 'name'",
"request body must have required property 'description'",
"request body must have required property 'contact_email'",
"request body must have required property 'ownerId'"
]
}
}
🔗 関連ドキュメント
- ユーザーサービス - ユーザー管理操作
- 認証サービス - 認証および認可
- エラーハンドリング - エラーパターンの理解
- スキーマコンポーネント - データ検証の概念
- カスタムサービステュートリアル - 独自サービスの構築