メインコンテンツまでスキップ
バージョン: 0.5.0 (最新)

🛒 オーダーサービス

Testing Status

オーダーサービスは、オーダーエンティティをCRUD操作で管理するための完全な REST API を提供します。NodeBlocks の関数型合成アプローチで構築され、MongoDB とシームレスに統合します。


🚀 クイックスタート

import express from 'express';
import { middlewares, services, drivers } from '@nodeblocks/backend-sdk';

const { nodeBlocksErrorMiddleware } = middlewares;
const { orderService } = services;
const { getMongoClient } = drivers;

const client = getMongoClient('mongodb://localhost:27017', 'dev');

express()
.use(
orderService(
{
orders: client.collection('orders'),
identities: client.collection('identities'),
},
{
authSecrets: {
authEncSecret: 'your-encryption-secret',
authSignSecret: 'your-signing-secret',
},
identity: {
typeIds: {
admin: '100',
guest: '000',
regular: '001',
},
},
}
)
)
.use(nodeBlocksErrorMiddleware())
.listen(8089, () => console.log('Server running'));

📋 エンドポイント概要

オーダー操作

メソッドパス説明認証必須
POST/orders新しいオーダーを作成✅ 必須
GET/orders/:orderIdIDでオーダーを取得✅ 必須
GET/ordersオーダーを一覧/フィルタ✅ 必須
PATCH/orders/:orderIdオーダーを更新✅ 必須
DELETE/orders/:orderIdオーダーを削除✅ 必須

🗄️ エンティティスキーマ

オーダーエンティティは、自動生成されるベースフィールドと、アイテム配列および価格を含む複雑なオーダー固有のデータで構成されます:

{
"items": [
{
"productId": "string (uuid)",
"quantity": "number",
"price": "number"
}
],
"total": "number",
"subtotal": "number",
"tax": "number",
"currency": "string",
"status": "string",
"identityId": "string (uuid)",
"organizationId": "string (uuid)",
"createdAt": "string (datetime)",
"id": "string",
"updatedAt": "string (datetime)"
}

フィールド詳細

フィールド自動生成必須説明
itemsarray製品詳細を含むオーダーアイテムの配列
totalnumberオーダー合計金額(最小0)
subtotalnumber税抜小計(最小0)
taxnumber税金額(最小0)
currencystring通貨コード(例: "USD", "EUR")
statusstringオーダーステータス(例: "pending", "completed")
identityIdstring (uuid)オーダーを発注したアイデンティティ
organizationIdstring (uuid)オーダーに関連付けられた組織
createdAtdatetime作成日時
idstring一意識別子(UUID)
updatedAtdatetime最終更新日時

アイテム配列スキーマ

items 配列内の各アイテムには以下のものが含まれている必要があります:

フィールド必須検証説明
productIdstring (uuid)UUID形式製品識別子
quantitynumber最小1注文数量
pricenumber最小0単価

📝 注意: スキーマは additionalProperties: false を強制するため、定義されたフィールドのみが許可されます。自動生成フィールドはサービス側で設定され、作成/更新リクエストに含めないでください。


🔐 認証ヘッダー

すべてのエンドポイントで、次のヘッダーを含めてください:

Authorization: Bearer <access_token>
x-nb-fingerprint: <device_fingerprint>

⚠️ 重要: 認可時にフィンガープリントを指定した場合、認証済みのすべてのリクエストで x-nb-fingerprint ヘッダーが必須です。欠如している場合は 401 Unauthorized が返ります。


🔧 APIエンドポイント

1. オーダー作成

アイテム配列と価格詳細を含む提供された情報で新しいオーダーを作成します。

リクエスト:

  • メソッド: POST
  • パス: /orders
  • ヘッダー:
    • Content-Type: application/json
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • 認可: ベアラートークン必須

リクエストボディ:

フィールド必須説明
itemsarrayオーダーアイテムの配列(アイテムスキーマ参照)
totalnumberオーダー合計金額
identityIdstring (uuid)オーダーを発注したアイデンティティ
subtotalnumber税抜小計
taxnumber税金額
currencystring通貨コード
statusstringオーダーステータス
organizationIdstring (uuid)オーダーに関連付けられた組織

レスポンスボディ:

フィールド説明
itemsarray製品詳細を含むオーダーアイテムの配列
items[].productIdstring製品識別子
items[].quantitynumber注文数量
items[].pricenumber単価
totalnumberオーダー合計金額
subtotalnumber税抜小計
taxnumber税金額
currencystring通貨コード
statusstringオーダーステータス
identityIdstringオーダーを発注したアイデンティティ
organizationIdstringオーダーに関連付けられた組織
createdAtstring作成日時
idstring一意のオーダー識別子
updatedAtstring最終更新日時

バリデーション:

  • スキーマ検証: 自動強制(items、total、identityId必須)
  • ルートバリデーション:
    • 認証済みリクエスト(ベアラー)必須
    • 管理者ロールまたは自己(オーダー所有者)必須

認可に関する注意: オーダーを作成する場合、リクエストボディ内の identityId フィールドは、アクセストークンに関連付けられた identityId一致する必要があります。別のアイデンティティのオーダーを作成しようとすると、403 Forbidden エラーが返されます。

管理者ユーザーは、バックエンドバリデーターロジックを変更して許可しない限り、他のユーザーのオーダーを作成できません。

リクエスト例:

curl -X POST http://localhost:8089/orders \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access_token>" \
-d '{
"identityId": "30000000-0000-4000-a000-000000000001",
"items": [
{
"productId": "10000000-0000-4000-a000-000000000001",
"quantity": 2,
"price": 50
},
{
"productId": "10000000-0000-4000-a000-000000000002",
"quantity": 1,
"price": 25
}
],
"subtotal": 125,
"tax": 12.5,
"total": 137.5,
"currency": "USD",
"status": "pending",
"organizationId": "20000000-0000-4000-a000-000000000001"
}'

成功レスポンス:

HTTP/1.1 200 OK
Content-Type: application/json

{
"currency": "USD",
"items": [
{
"productId": "10000000-0000-4000-a000-000000000001",
"quantity": 2,
"price": 50
},
{
"productId": "10000000-0000-4000-a000-000000000002",
"quantity": 1,
"price": 25
}
],
"organizationId": "20000000-0000-4000-a000-000000000001",
"identityId": "30000000-0000-4000-a000-000000000001",
"subtotal": 125,
"tax": 12.5,
"total": 137.5,
"status": "pending",
"createdAt": "2025-07-04T01:59:20.084Z",
"id": "10283907-d41a-4647-a235-18ec63f3369a",
"updatedAt": "2025-07-04T01:59:20.084Z"
}

エラーレスポンス:

リクエストボディに必須フィールドがない場合:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": {
"message": "Validation Error",
"data": [
"request body must have required property 'identityId'",
"request body must have required property 'items'"
]
}
}

認証が失敗した場合:

HTTP/1.1 401 Unauthorized
Content-Type: application/json

{
"error": {
"message": "token could not be verified"
}
}

認可が失敗した場合:

HTTP/1.1 403 Forbidden
Content-Type: application/json

{
"error": {
"message": "User is not authorized to access this order"
}
}

2. IDでオーダー取得

一意のIDで特定のオーダーを取得します。

リクエスト:

  • メソッド: GET
  • パス: /orders/:orderId
  • ヘッダー:
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • 認可: ベアラートークン必須

URL パラメータ:

パラメータ必須説明
orderIdstring一意のオーダー識別子

レスポンスボディ:

フィールド説明
itemsarray製品詳細を含むオーダーアイテムの配列
items[].productIdstring製品識別子
items[].quantitynumber注文数量
items[].pricenumber単価
totalnumberオーダー合計金額
subtotalnumber税抜小計
taxnumber税金額
currencystring通貨コード
statusstringオーダーステータス
identityIdstringオーダーを発注したアイデンティティ
organizationIdstringオーダーに関連付けられた組織
createdAtstring作成日時
idstring一意のオーダー識別子
updatedAtstring最終更新日時

バリデーション:

  • スキーマ検証: なし(GET リクエスト)
  • ルートバリデーション:
    • 認証済みリクエスト(ベアラー)必須
    • 管理者ロールまたはオーダー所有権必須

リクエスト例:

curl http://localhost:8089/orders/10283907-d41a-4647-a235-18ec63f3369a \
-H "Authorization: Bearer <access_token>"

成功レスポンス:

HTTP/1.1 200 OK
Content-Type: application/json

{
"currency": "USD",
"items": [
{
"productId": "10000000-0000-4000-a000-000000000001",
"quantity": 2,
"price": 50
},
{
"productId": "10000000-0000-4000-a000-000000000002",
"quantity": 1,
"price": 25
}
],
"organizationId": "20000000-0000-4000-a000-000000000001",
"identityId": "30000000-0000-4000-a000-000000000001",
"subtotal": 125,
"tax": 12.5,
"total": 137.5,
"status": "completed",
"createdAt": "2025-07-04T01:59:20.084Z",
"id": "10283907-d41a-4647-a235-18ec63f3369a",
"updatedAt": "2025-07-07T08:11:16.176Z"
}

エラーレスポンス:

指定IDのオーダーが存在しない場合:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": {
"message": "Order not found"
}
}

3. オーダー一覧

フィルタやページングを指定してオーダーの一覧を取得します。

リクエスト:

  • メソッド: GET
  • パス: /orders
  • ヘッダー:
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • 認可: ベアラートークン必須

クエリパラメータ:

パラメータ必須説明
currencystring通貨でフィルタ
organizationIdstring組織でフィルタ
statusstringステータスでフィルタ
subtotalnumber小計金額でフィルタ
taxnumber税金額でフィルタ
totalnumber合計金額でフィルタ
identityIdstringidentityIdでフィルタ
pagenumberページングのページ番号
limitnumber1ページあたりの件数

レスポンスボディ:

フィールド説明
itemsarray製品詳細を含むオーダーアイテムの配列
items[].productIdstring製品識別子
items[].quantitynumber注文数量
items[].pricenumber単価
totalnumberオーダー合計金額
subtotalnumber税抜小計
taxnumber税金額
currencystring通貨コード
statusstringオーダーステータス
identityIdstringオーダーを発注したアイデンティティ
organizationIdstringオーダーに関連付けられた組織
createdAtstring作成日時
idstring一意のオーダー識別子
updatedAtstring最終更新日時

バリデーション:

  • スキーマ検証: なし(GET リクエスト)
  • ルートバリデーション:
    • 認証済みリクエスト(ベアラー)必須
    • 管理者ロールまたは自己必須

リクエスト例:

全件取得:

curl http://localhost:8089/orders \
-H "Authorization: Bearer <access_token>"

ステータスでフィルタ:

curl "http://localhost:8089/orders?status=completed" \
-H "Authorization: Bearer <access_token>"

通貨でフィルタ:

curl "http://localhost:8089/orders?currency=USD" \
-H "Authorization: Bearer <access_token>"

成功レスポンス:

HTTP/1.1 200 OK
Content-Type: application/json

[
{
"currency": "USD",
"items": [
{
"productId": "10000000-0000-4000-a000-000000000001",
"quantity": 2,
"price": 50
},
{
"productId": "10000000-0000-4000-a000-000000000002",
"quantity": 1,
"price": 25
}
],
"organizationId": "20000000-0000-4000-a000-000000000001",
"identityId": "30000000-0000-4000-a000-000000000001",
"subtotal": 125,
"tax": 12.5,
"total": 137.5,
"status": "completed",
"createdAt": "2025-07-04T01:59:20.084Z",
"id": "10283907-d41a-4647-a235-18ec63f3369a",
"updatedAt": "2025-07-07T08:11:16.176Z"
}
]

4. オーダー更新

部分更新で既存のオーダーを更新します。

リクエスト:

  • メソッド: PATCH
  • パス: /orders/:orderId
  • ヘッダー:
    • Content-Type: application/json
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • 認可: ベアラートークン必須

URL パラメータ:

パラメータ必須説明
orderIdstring一意のオーダー識別子

リクエストボディ(全フィールド任意):

フィールド必須説明
itemsarrayオーダーアイテムの配列
totalnumberオーダー合計金額
subtotalnumber税抜小計
taxnumber税金額
currencystring通貨コード
statusstringオーダーステータス
identityIdstring (uuid)オーダーを発注したアイデンティティ
organizationIdstring (uuid)オーダーに関連付けられた組織

レスポンスボディ:

フィールド説明
itemsarray製品詳細を含むオーダーアイテムの配列
items[].productIdstring製品識別子
items[].quantitynumber注文数量
items[].pricenumber単価
totalnumber更新後のオーダー合計金額
subtotalnumber更新後の税抜小計
taxnumber更新後の税金額
currencystring更新後の通貨コード
statusstring更新後のオーダーステータス
identityIdstringオーダーを発注したアイデンティティ
organizationIdstring更新後のオーダーに関連付けられた組織
createdAtstring作成日時
idstring一意のオーダー識別子
updatedAtstring最終更新日時

バリデーション:

  • スキーマ検証: 自動強制(部分更新、全フィールド任意)
  • ルートバリデーション:
    • 認証済みリクエスト(ベアラー)必須
    • 管理者ロールまたはオーダー所有権必須

リクエスト例:

curl -X PATCH http://localhost:8089/orders/10283907-d41a-4647-a235-18ec63f3369a \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access_token>" \
-d '{"status": "completed"}'

成功レスポンス:

HTTP/1.1 200 OK
Content-Type: application/json

{
"currency": "USD",
"items": [
{
"productId": "10000000-0000-4000-a000-000000000001",
"quantity": 2,
"price": 50
},
{
"productId": "10000000-0000-4000-a000-000000000002",
"quantity": 1,
"price": 25
}
],
"organizationId": "20000000-0000-4000-a000-000000000001",
"identityId": "30000000-0000-4000-a000-000000000001",
"subtotal": 125,
"tax": 12.5,
"total": 137.5,
"status": "completed",
"createdAt": "2025-07-04T01:59:20.084Z",
"id": "10283907-d41a-4647-a235-18ec63f3369a",
"updatedAt": "2025-07-07T08:11:16.176Z"
}

エラーレスポンス:

指定IDのオーダーが存在しない場合:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": {
"message": "Order not found"
}
}

5. オーダー削除

システムからオーダーを完全に削除します。

リクエスト:

  • メソッド: DELETE
  • パス: /orders/:orderId
  • ヘッダー:
    • Authorization: Bearer <token>
    • x-nb-fingerprint: <device-fingerprint>
  • 認可: ベアラートークン必須

URL パラメータ:

パラメータ必須説明
orderIdstring一意のオーダー識別子

レスポンスボディ:

フィールド説明
なし-成功時はレスポンスボディなし

バリデーション:

  • ルートバリデーション:
    • 認証済みリクエスト(ベアラー)必須
    • 管理者ロールまたはオーダー所有権必須

リクエスト例:

curl -X DELETE http://localhost:8089/orders/10283907-d41a-4647-a235-18ec63f3369a \
-H "Authorization: Bearer <access_token>"

成功レスポンス:

HTTP/1.1 204 No Content

エラーレスポンス:

指定IDのオーダーが存在しない場合:

HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": {
"message": "Order not found"
}
}

⚙️ 設定オプション

サービス設定

interface OrderServiceConfiguration {
authSecrets: {
authEncSecret: string; // JWT 暗号化シークレット
authSignSecret: string; // JWT 署名シークレット
};
identity?: {
typeIds?: {
admin: string; // 管理者ユーザー種別識別子
guest: string; // ゲストユーザー種別識別子
regular: string; // 一般ユーザー種別識別子
};
};
}

設定詳細

オーダーサービスの設定は、セキュリティとユーザー種別管理の論理グループに整理されています。

🔐 セキュリティ設定

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"

設定例

const orderConfig = {
authSecrets: {
authEncSecret: process.env.AUTH_ENC_SECRET || 'your-enc-secret',
authSignSecret: process.env.AUTH_SIGN_SECRET || 'your-sign-secret'
},
user: {
typeIds: {
admin: 'administrator',
guest: 'visitor',
user: 'member'
}
}
};

🚨 エラーハンドリング

オーダーサービスのエラーは、適切なHTTPステータスコードとJSON形式で返されます:

代表的なエラーコード

ステータスエラーメッセージ説明
400Validation Errorリクエストボディ形式が無効または必須フィールドがない
400request body must have required property 'identityId'リクエストボディに identityId フィールドがない
400request body must have required property 'items'リクエストボディに items 配列がない
400request body must have required property 'total'リクエストボディに total フィールドがない
400request body must NOT have additional propertiesリクエストにサポートされていないフィールドが含まれている
400Failed to create orderデータベース挿入操作が挿入されたIDを返せなかった
400Failed to update order更新操作でデータが変更されない(変更なし)
400Failed to delete orderデータベース削除操作が失敗した
401token could not be verified認可トークンがない/無効
401Authentication failed認証トークンがない/無効
401Token fails security checkトークンのセキュリティ検証が失敗した
403User is not authorized to access this order必要な権限がない(管理者/所有者アクセス)
403User is not authorized to access this resource必要な権限がない(管理者アクセス)
404Order not found要求された操作の対象オーダーが存在しない
500Failed to create order作成中のDB接続問題/予期せぬ失敗
500Failed to get order取得中のDB接続問題/予期せぬ失敗
500Failed to find orders一覧取得中のDB接続問題/フィルタ構文不正/予期せぬ失敗
500Failed to update order更新中のDB接続問題/予期せぬ失敗
500Failed to delete order削除中のDB接続問題/予期せぬ失敗

エラーレスポンス形式

{
"error": {
"message": "Error message description",
"data": ["Additional error details"]
}
}

検証エラーには追加の詳細が含まれます:

{
"error": {
"message": "Validation Error",
"data": [
"request body must have required property 'items'",
"request body must have required property 'total'"
]
}
}

🔗 関連ドキュメント