Notebookbeheer

Volledige CRUD-operaties voor het beheren van notebooks binnen onderzoeken. Alle wijzigingsoperaties laden automatisch het project in de gedeelde cache.


Notebooks Lijst

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

Geeft alle notebooks binnen een onderzoek terug.

Padparameters

Parameter Type Vereist Beschrijving
tenantId GUID Ja De tenantidentificatie
projectId GUID Ja De projectidentificatie
investigationId GUID Ja De onderzoekidentificatie

Respons (200 OK)

[
  {
    "notebookId": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
    "investigationId": "11111111-2222-3333-4444-555555555555",
    "name": "Main",
    "description": "Primair analyse-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": "Proces variant verkenning",
    "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
  }
]

Foutreacties

Niet Gevonden (404)

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

Notebook Ophalen

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

Geeft gedetailleerde informatie terug over een specifiek notebook.

Padparameters

Parameter Type Vereist Beschrijving
tenantId GUID Ja De tenantidentificatie
projectId GUID Ja De projectidentificatie
notebookId GUID Ja De notebookidentificatie

Respons (200 OK)

{
  "notebookId": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
  "investigationId": "11111111-2222-3333-4444-555555555555",
  "name": "Main",
  "description": "Primair analyse-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
}

Notebook Aanmaken

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

Maakt een nieuwe lege notebook aan binnen het onderzoek.

Padparameters

Parameter Type Vereist Beschrijving
tenantId GUID Ja De tenantidentificatie
projectId GUID Ja De projectidentificatie
investigationId GUID Ja De onderzoekidentificatie

Verzoekbody

{
  "name": "Process Analysis",
  "description": "Gedetailleerde procesanalyse workflow",
  "notebookType": 0
}

Verzoekvelden

Veld Type Vereist Beschrijving
name string Ja Notebooknaam (uniek binnen onderzoek)
description string Nee Notebookbeschrijving
notebookType integer Nee Type (0=Standaard, standaardwaarde)

Respons (201 Created)

{
  "notebookId": "cccccccc-dddd-eeee-ffff-000000000000",
  "investigationId": "11111111-2222-3333-4444-555555555555",
  "name": "Process Analysis",
  "description": "Gedetailleerde procesanalyse 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
}

Foutreacties

Slechte aanvraag (400)

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

Aanmaken Vanuit Sjabloon

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

Maakt een notebook aan vanuit een vooraf gedefinieerd sjabloon, inclusief alle blokken en configuraties.

Padparameters

Parameter Type Vereist Beschrijving
tenantId GUID Ja De tenantidentificatie
projectId GUID Ja De projectidentificatie
investigationId GUID Ja De onderzoekidentificatie

Verzoekbody

{
  "templateId": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
  "name": "Process Discovery Analysis",
  "description": "Analyse met Process Discovery sjabloon"
}

Verzoekvelden

Veld Type Vereist Beschrijving
templateId GUID Ja Te gebruiken sjabloon
name string Nee Overschrijf sjabloonnaam
description string Nee Overschrijf sjabloonbeschrijving

Respons (201 Created)

Geeft het aangemaakte notebook terug met blokken uit het sjabloon.

Foutreacties

Niet Gevonden (404)

{
  "Error": "Template not found"
}

Notebook Bijwerken

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

Werk notebookmetadata bij. Ondersteunt optimistische locking via DateModified.

Padparameters

Parameter Type Vereist Beschrijving
tenantId GUID Ja De tenantidentificatie
projectId GUID Ja De projectidentificatie
notebookId GUID Ja De notebookidentificatie

Verzoekbody

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

Verzoekvelden

Veld Type Vereist Beschrijving
name string Ja Notebooknaam
description string Nee Notebookbeschrijving
notebookOrder decimal Nee Weergavevolgorde
dateModified datetime Nee Voor optimistische locking

Respons (200 OK)

Geeft het bijgewerkte notebook terug.

Optimistische Locking

Als dateModified is opgegeven en niet overeenkomt met de huidige serverwaarde, wordt 409 Conflict geretourneerd:

{
  "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"
}

Notebook Verwijderen

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

Verwijdert een notebook en alle bijbehorende blokken permanent.

Padparameters

Parameter Type Vereist Beschrijving
tenantId GUID Ja De tenantidentificatie
projectId GUID Ja De projectidentificatie
notebookId GUID Ja De notebookidentificatie

Respons (200 OK)

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

Notebook Kopiƫren

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

Maakt een volledige kopie van een notebook inclusief alle blokken. Kan worden gekopieerd naar hetzelfde of een ander onderzoek.

Padparameters

Parameter Type Vereist Beschrijving
tenantId GUID Ja De tenantidentificatie
projectId GUID Ja De projectidentificatie
notebookId GUID Ja Bron-notebookidentificatie

Verzoekbody

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

Verzoekvelden

Veld Type Vereist Beschrijving
name string Nee Naam voor kopie (standaard: "Copy of ")
destinationInvestigationId GUID Nee Doelonderzoek (standaard: hetzelfde onderzoek)

Respons (201 Created)

Geeft de nieuw aangemaakte notebookkopie terug.


Deelbare URL Ophalen

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

Genereert een deelbare URL voor directe toegang tot het notebook in de UI.

Respons (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
}

Implementatie Voorbeelden

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):
        """Lijst alle notebooks in een onderzoek."""
        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):
        """Haal notebookdetails op."""
        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):
        """Maak een nieuw notebook aan."""
        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):
        """Maak notebook aan vanuit sjabloon."""
        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):
        """Werk notebook bij met optimistische locking."""
        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):
        """Verwijder een notebook."""
        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):
        """Kopieer een notebook."""
        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()

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

# Lijst notebooks
notebooks = manager.list_notebooks(investigation_id)
print(f"Vond {len(notebooks)} notebooks")

# Maak een notebook aan
notebook = manager.create_notebook(investigation_id, 'New Analysis', 'My workflow')
print(f"Notebook gemaakt: {notebook['notebookId']}")

# Kopieer het notebook
copy = manager.copy_notebook(notebook['notebookId'], 'Copy of New Analysis')
print(f"Kopie gemaakt: {copy['notebookId']}")

# Bijwerken met optimistische locking
try:
    updated = manager.update_notebook(
        notebook['notebookId'],
        'Renamed Analysis',
        date_modified=notebook['dateModified']
    )
except Exception as e:
    print(f"Bijwerken mislukt: {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(`Mislukt: ${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(`Mislukt: ${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(`Mislukt: ${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(`Mislukt: ${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(`Mislukt: ${response.status}`);
    return response.json();
  }
}

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

// Lijst notebooks
const notebooks = await manager.listNotebooks(investigationId);
console.log(`Vond ${notebooks.length} notebooks`);

// Maak en kopieer
const notebook = await manager.createNotebook(investigationId, 'New Analysis');
const copy = await manager.copyNotebook(notebook.notebookId, 'Copy of Analysis');

Beste Praktijken

  1. Automatisch laden: Laad projecten niet expliciet voor notebook CRUD - het is automatisch
  2. Optimistische locking: Neem dateModified op bij updates om conflicten te detecteren
  3. Sjablonen: Gebruik sjablonen voor consistente analyse-workflows
  4. Naamgeving: Gebruik beschrijvende namen die uniek zijn binnen elk onderzoek
  5. Opruimen: Verwijder ongebruikte notebooks om onderzoeken overzichtelijk te houden