ノートブック管理

調査内のノートブックを管理するための完全なCRUD操作。すべての変更操作は自動的にプロジェクトを共有キャッシュにロードします。


ノートブック一覧取得

GET /api/{tenantId}/{projectId}/notebook/investigation/{investigationId}

調査内のすべてのノートブックを返します。

パスパラメータ

パラメータ 必須 説明
tenantId GUID はい テナント識別子
projectId GUID はい プロジェクト識別子
investigationId GUID はい 調査識別子

レスポンス (200 OK)

[
  {
    "notebookId": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
    "investigationId": "11111111-2222-3333-4444-555555555555",
    "name": "Main",
    "description": "Primary analysis notebook",
    "dateCreated": "2024-01-15T10:30:00Z",
    "dateModified": "2024-01-20T14:45:00Z",
    "createdBy": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "modifiedBy": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "notebookType": 0,
    "notebookOrder": 1.0,
    "lastExecutionDuration": 2.5,
    "blockCount": 12
  },
  {
    "notebookId": "bbbbbbbb-cccc-dddd-eeee-ffffffffffff",
    "investigationId": "11111111-2222-3333-4444-555555555555",
    "name": "Variant Analysis",
    "description": "Process variant exploration",
    "dateCreated": "2024-01-16T09:00:00Z",
    "dateModified": "2024-01-18T11:30:00Z",
    "createdBy": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "modifiedBy": null,
    "notebookType": 0,
    "notebookOrder": 2.0,
    "lastExecutionDuration": 1.2,
    "blockCount": 8
  }
]

エラー応答

Not Found (404)

{
  "Error": "Investigation not found",
  "InvestigationId": "11111111-2222-3333-4444-555555555555"
}

ノートブック取得

GET /api/{tenantId}/{projectId}/notebook/{notebookId}

特定のノートブックの詳細情報を返します。

パスパラメータ

パラメータ 必須 説明
tenantId GUID はい テナント識別子
projectId GUID はい プロジェクト識別子
notebookId GUID はい ノートブック識別子

レスポンス (200 OK)

{
  "notebookId": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
  "investigationId": "11111111-2222-3333-4444-555555555555",
  "name": "Main",
  "description": "Primary analysis notebook",
  "dateCreated": "2024-01-15T10:30:00Z",
  "dateModified": "2024-01-20T14:45:00Z",
  "createdBy": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "modifiedBy": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "notebookType": 0,
  "notebookOrder": 1.0,
  "lastExecutionDuration": 2.5,
  "blockCount": 12
}

ノートブック作成

POST /api/{tenantId}/{projectId}/notebook/investigation/{investigationId}

調査内に新しい空のノートブックを作成します。

パスパラメータ

パラメータ 必須 説明
tenantId GUID はい テナント識別子
projectId GUID はい プロジェクト識別子
investigationId GUID はい 調査識別子

リクエストボディ

{
  "name": "Process Analysis",
  "description": "Detailed process analysis workflow",
  "notebookType": 0
}

リクエスト項目

項目 必須 説明
name string はい ノートブック名(調査内で一意)
description string いいえ ノートブックの説明
notebookType integer いいえ 種類(0=標準、デフォルト)

レスポンス (201 Created)

{
  "notebookId": "cccccccc-dddd-eeee-ffff-000000000000",
  "investigationId": "11111111-2222-3333-4444-555555555555",
  "name": "Process Analysis",
  "description": "Detailed process analysis workflow",
  "dateCreated": "2024-03-01T10:00:00Z",
  "dateModified": "2024-03-01T10:00:00Z",
  "createdBy": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "modifiedBy": null,
  "notebookType": 0,
  "notebookOrder": 3.0,
  "lastExecutionDuration": 0,
  "blockCount": 0
}

エラー応答

Bad Request (400)

{
  "Error": "Failed to create notebook. The name may already exist in this investigation."
}

テンプレートから作成

POST /api/{tenantId}/{projectId}/notebook/investigation/{investigationId}/from-template

あらかじめ定義されたテンプレートから、すべてのブロックや設定を含むノートブックを作成します。

パスパラメータ

パラメータ 必須 説明
tenantId GUID はい テナント識別子
projectId GUID はい プロジェクト識別子
investigationId GUID はい 調査識別子

リクエストボディ

{
  "templateId": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
  "name": "Process Discovery Analysis",
  "description": "Analysis using Process Discovery template"
}

リクエスト項目

項目 必須 説明
templateId GUID はい 使用するテンプレート
name string いいえ テンプレート名の上書き
description string いいえ テンプレート説明の上書き

レスポンス (201 Created)

テンプレートからのブロックを含む作成されたノートブックを返します。

エラー応答

Not Found (404)

{
  "Error": "Template not found"
}

ノートブック更新

PUT /api/{tenantId}/{projectId}/notebook/{notebookId}

ノートブックのメタデータを更新します。DateModified による楽観的ロックをサポートしています。

パスパラメータ

パラメータ 必須 説明
tenantId GUID はい テナント識別子
projectId GUID はい プロジェクト識別子
notebookId GUID はい ノートブック識別子

リクエストボディ

{
  "name": "Updated Notebook Name",
  "description": "Updated description",
  "notebookOrder": 2.5,
  "dateModified": "2024-01-20T14:45:00Z"
}

リクエスト項目

項目 必須 説明
name string はい ノートブック名
description string いいえ ノートブック説明
notebookOrder decimal いいえ 表示順序
dateModified datetime いいえ 楽観的ロック用

レスポンス (200 OK)

更新されたノートブックを返します。

楽観的ロック

dateModified が提供されサーバーの現在値と一致しない場合、409 Conflict を返します:

{
  "Error": "CONFLICT",
  "Message": "Notebook was modified by another user since you last fetched it",
  "YourDateModified": "2024-01-20T14:45:00Z",
  "CurrentDateModified": "2024-01-21T09:30:00Z",
  "ModifiedBy": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "Resolution": "GET /api/{tenantId}/{projectId}/notebook/{notebookId} to fetch current state, then retry"
}

ノートブック削除

DELETE /api/{tenantId}/{projectId}/notebook/{notebookId}

ノートブックとそのすべてのブロックを完全に削除します。

パスパラメータ

パラメータ 必須 説明
tenantId GUID はい テナント識別子
projectId GUID はい プロジェクト識別子
notebookId GUID はい ノートブック識別子

レスポンス (200 OK)

{
  "Message": "Notebook successfully deleted",
  "NotebookId": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
}

ノートブック複製

POST /api/{tenantId}/{projectId}/notebook/{notebookId}/copy

すべてのブロックを含むノートブックの完全なコピーを作成します。同じ調査または別の調査へのコピーが可能です。

パスパラメータ

パラメータ 必須 説明
tenantId GUID はい テナント識別子
projectId GUID はい プロジェクト識別子
notebookId GUID はい コピー元ノートブック識別子

リクエストボディ

{
  "name": "Copy of Main Analysis",
  "destinationInvestigationId": "22222222-3333-4444-5555-666666666666"
}

リクエスト項目

項目 必須 説明
name string いいえ コピーの名前(デフォルト: "Copy of ")
destinationInvestigationId GUID いいえ コピー先の調査(デフォルト: 同一調査)

レスポンス (201 Created)

作成されたノートブックのコピーを返します。


共有可能URL取得

GET /api/{tenantId}/{projectId}/notebook/{notebookId}/url

UIでノートブックに直接アクセスするための共有可能なURLを生成します。

レスポンス (200 OK)

{
  "notebookId": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
  "url": "https://your-mindzie-instance.com/investigation/12345678/87654321/11111111/notebook/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
  "relativePath": "/investigation/12345678/87654321/11111111/notebook/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
  "expiresAt": null
}

実装例

Python

import requests

BASE_URL = 'https://your-mindzie-instance.com'
TENANT_ID = '12345678-1234-1234-1234-123456789012'
PROJECT_ID = '87654321-4321-4321-4321-210987654321'

class NotebookManager:
    def __init__(self, api_key):
        self.headers = {
            'Authorization': f'Bearer {api_key}',
            'Content-Type': 'application/json'
        }

    def list_notebooks(self, investigation_id):
        """調査内のすべてのノートブックを一覧表示します。"""
        url = f'{BASE_URL}/api/{TENANT_ID}/{PROJECT_ID}/notebook/investigation/{investigation_id}'
        response = requests.get(url, headers=self.headers)
        response.raise_for_status()
        return response.json()

    def get_notebook(self, notebook_id):
        """ノートブックの詳細を取得します。"""
        url = f'{BASE_URL}/api/{TENANT_ID}/{PROJECT_ID}/notebook/{notebook_id}'
        response = requests.get(url, headers=self.headers)
        response.raise_for_status()
        return response.json()

    def create_notebook(self, investigation_id, name, description=None):
        """新しいノートブックを作成します。"""
        url = f'{BASE_URL}/api/{TENANT_ID}/{PROJECT_ID}/notebook/investigation/{investigation_id}'
        data = {'name': name, 'description': description}
        response = requests.post(url, json=data, headers=self.headers)
        response.raise_for_status()
        return response.json()

    def create_from_template(self, investigation_id, template_id, name=None):
        """テンプレートからノートブックを作成します。"""
        url = f'{BASE_URL}/api/{TENANT_ID}/{PROJECT_ID}/notebook/investigation/{investigation_id}/from-template'
        data = {'templateId': template_id, 'name': name}
        response = requests.post(url, json=data, headers=self.headers)
        response.raise_for_status()
        return response.json()

    def update_notebook(self, notebook_id, name, description=None, date_modified=None):
        """楽観的ロック付きでノートブックを更新します。"""
        url = f'{BASE_URL}/api/{TENANT_ID}/{PROJECT_ID}/notebook/{notebook_id}'
        data = {'name': name, 'description': description}
        if date_modified:
            data['dateModified'] = date_modified
        response = requests.put(url, json=data, headers=self.headers)
        if response.status_code == 409:
            conflict = response.json()
            raise Exception(f"Conflict: {conflict['Message']}")
        response.raise_for_status()
        return response.json()

    def delete_notebook(self, notebook_id):
        """ノートブックを削除します。"""
        url = f'{BASE_URL}/api/{TENANT_ID}/{PROJECT_ID}/notebook/{notebook_id}'
        response = requests.delete(url, headers=self.headers)
        response.raise_for_status()
        return response.json()

    def copy_notebook(self, notebook_id, name=None, destination_investigation=None):
        """ノートブックをコピーします。"""
        url = f'{BASE_URL}/api/{TENANT_ID}/{PROJECT_ID}/notebook/{notebook_id}/copy'
        data = {'name': name}
        if destination_investigation:
            data['destinationInvestigationId'] = destination_investigation
        response = requests.post(url, json=data, headers=self.headers)
        response.raise_for_status()
        return response.json()

# 使用例
manager = NotebookManager('your-api-key')
investigation_id = '11111111-2222-3333-4444-555555555555'

# ノートブック一覧
notebooks = manager.list_notebooks(investigation_id)
print(f"見つかったノートブック数: {len(notebooks)}")

# ノートブック作成
notebook = manager.create_notebook(investigation_id, 'New Analysis', 'My workflow')
print(f"作成されたノートブックID: {notebook['notebookId']}")

# ノートブック複製
copy = manager.copy_notebook(notebook['notebookId'], 'Copy of New Analysis')
print(f"作成されたコピーID: {copy['notebookId']}")

# 楽観的ロックを使った更新
try:
    updated = manager.update_notebook(
        notebook['notebookId'],
        'Renamed Analysis',
        date_modified=notebook['dateModified']
    )
except Exception as e:
    print(f"更新失敗: {e}")

JavaScript/Node.js

const BASE_URL = 'https://your-mindzie-instance.com';
const TENANT_ID = '12345678-1234-1234-1234-123456789012';
const PROJECT_ID = '87654321-4321-4321-4321-210987654321';

class NotebookManager {
  constructor(apiKey) {
    this.headers = {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json'
    };
  }

  async listNotebooks(investigationId) {
    const url = `${BASE_URL}/api/${TENANT_ID}/${PROJECT_ID}/notebook/investigation/${investigationId}`;
    const response = await fetch(url, { headers: this.headers });
    if (!response.ok) throw new Error(`Failed: ${response.status}`);
    return response.json();
  }

  async createNotebook(investigationId, name, description = null) {
    const url = `${BASE_URL}/api/${TENANT_ID}/${PROJECT_ID}/notebook/investigation/${investigationId}`;
    const response = await fetch(url, {
      method: 'POST',
      headers: this.headers,
      body: JSON.stringify({ name, description })
    });
    if (!response.ok) throw new Error(`Failed: ${response.status}`);
    return response.json();
  }

  async updateNotebook(notebookId, name, description = null, dateModified = null) {
    const url = `${BASE_URL}/api/${TENANT_ID}/${PROJECT_ID}/notebook/${notebookId}`;
    const body = { name, description };
    if (dateModified) body.dateModified = dateModified;

    const response = await fetch(url, {
      method: 'PUT',
      headers: this.headers,
      body: JSON.stringify(body)
    });

    if (response.status === 409) {
      const conflict = await response.json();
      throw new Error(`Conflict: ${conflict.Message}`);
    }
    if (!response.ok) throw new Error(`Failed: ${response.status}`);
    return response.json();
  }

  async deleteNotebook(notebookId) {
    const url = `${BASE_URL}/api/${TENANT_ID}/${PROJECT_ID}/notebook/${notebookId}`;
    const response = await fetch(url, {
      method: 'DELETE',
      headers: this.headers
    });
    if (!response.ok) throw new Error(`Failed: ${response.status}`);
    return response.json();
  }

  async copyNotebook(notebookId, name = null, destinationInvestigationId = null) {
    const url = `${BASE_URL}/api/${TENANT_ID}/${PROJECT_ID}/notebook/${notebookId}/copy`;
    const body = {};
    if (name) body.name = name;
    if (destinationInvestigationId) body.destinationInvestigationId = destinationInvestigationId;

    const response = await fetch(url, {
      method: 'POST',
      headers: this.headers,
      body: JSON.stringify(body)
    });
    if (!response.ok) throw new Error(`Failed: ${response.status}`);
    return response.json();
  }
}

// 使用例
const manager = new NotebookManager('your-api-key');
const investigationId = '11111111-2222-3333-4444-555555555555';

// ノートブック一覧取得
const notebooks = await manager.listNotebooks(investigationId);
console.log(`見つかったノートブック数: ${notebooks.length}`);

// 作成と複製
const notebook = await manager.createNotebook(investigationId, 'New Analysis');
const copy = await manager.copyNotebook(notebook.notebookId, 'Copy of Analysis');

ベストプラクティス

  1. 自動ロード: ノートブックCRUDのために明示的にプロジェクトをロードする必要はありません - 自動的に行われます。
  2. 楽観的ロック: 競合検出のために更新時にdateModifiedを含めてください。
  3. テンプレート活用: 一貫した分析ワークフローのためにテンプレートを利用してください。
  4. 命名規則: 各調査内で一意かつ説明的な名前を使用してください。
  5. 整理整頓: 使用していないノートブックは削除して調査の整理を保ちましょう。