Gestion des Carnets de Notes
Opérations CRUD complètes pour la gestion des carnets de notes dans le cadre des investigations. Toutes les opérations de modification chargent automatiquement le projet dans le cache partagé.
Liste des Carnets de Notes
GET /api/{tenantId}/{projectId}/notebook/investigation/{investigationId}
Retourne tous les carnets de notes d'une investigation.
Paramètres de chemin
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
tenantId |
GUID | Oui | Identifiant du locataire |
projectId |
GUID | Oui | Identifiant du projet |
investigationId |
GUID | Oui | Identifiant de l'investigation |
Réponse (200 OK)
[
{
"notebookId": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"investigationId": "11111111-2222-3333-4444-555555555555",
"name": "Main",
"description": "Carnet d'analyse principal",
"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": "Analyse de Variantes",
"description": "Exploration des variantes de processus",
"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
}
]
Réponses d'erreur
Non trouvé (404)
{
"Error": "Investigation non trouvée",
"InvestigationId": "11111111-2222-3333-4444-555555555555"
}
Obtenir un Carnet de Notes
GET /api/{tenantId}/{projectId}/notebook/{notebookId}
Retourne les informations détaillées d'un carnet de notes spécifique.
Paramètres de chemin
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
tenantId |
GUID | Oui | Identifiant du locataire |
projectId |
GUID | Oui | Identifiant du projet |
notebookId |
GUID | Oui | Identifiant du carnet de notes |
Réponse (200 OK)
{
"notebookId": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"investigationId": "11111111-2222-3333-4444-555555555555",
"name": "Main",
"description": "Carnet d'analyse principal",
"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
}
Créer un Carnet de Notes
POST /api/{tenantId}/{projectId}/notebook/investigation/{investigationId}
Crée un nouveau carnet de notes vide dans l'investigation.
Paramètres de chemin
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
tenantId |
GUID | Oui | Identifiant du locataire |
projectId |
GUID | Oui | Identifiant du projet |
investigationId |
GUID | Oui | Identifiant de l'investigation |
Corps de la requête
{
"name": "Analyse de Processus",
"description": "Flux de travail d'analyse détaillée du processus",
"notebookType": 0
}
Champs de la requête
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
name |
string | Oui | Nom du carnet (unique dans l'investigation) |
description |
string | Non | Description du carnet |
notebookType |
integer | Non | Type (0=Standard, défaut) |
Réponse (201 Created)
{
"notebookId": "cccccccc-dddd-eeee-ffff-000000000000",
"investigationId": "11111111-2222-3333-4444-555555555555",
"name": "Analyse de Processus",
"description": "Flux de travail d'analyse détaillée du processus",
"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
}
Réponses d'erreur
Requête incorrecte (400)
{
"Error": "Échec de la création du carnet. Le nom peut déjà exister dans cette investigation."
}
Créer à partir d'un Modèle
POST /api/{tenantId}/{projectId}/notebook/investigation/{investigationId}/from-template
Crée un carnet de notes à partir d'un modèle prédéfini, incluant tous les blocs et configurations.
Paramètres de chemin
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
tenantId |
GUID | Oui | Identifiant du locataire |
projectId |
GUID | Oui | Identifiant du projet |
investigationId |
GUID | Oui | Identifiant de l'investigation |
Corps de la requête
{
"templateId": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"name": "Analyse Processus Découverte",
"description": "Analyse utilisant le modèle Process Discovery"
}
Champs de la requête
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
templateId |
GUID | Oui | Modèle à utiliser |
name |
string | Non | Remplace le nom du modèle |
description |
string | Non | Remplace la description du modèle |
Réponse (201 Created)
Retourne le carnet créé avec les blocs du modèle.
Réponses d'erreur
Non trouvé (404)
{
"Error": "Modèle non trouvé"
}
Mettre à Jour un Carnet de Notes
PUT /api/{tenantId}/{projectId}/notebook/{notebookId}
Met à jour les métadonnées du carnet. Supporte le verrouillage optimiste via DateModified.
Paramètres de chemin
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
tenantId |
GUID | Oui | Identifiant du locataire |
projectId |
GUID | Oui | Identifiant du projet |
notebookId |
GUID | Oui | Identifiant du carnet |
Corps de la requête
{
"name": "Nom du Carnet Mis à Jour",
"description": "Description mise à jour",
"notebookOrder": 2.5,
"dateModified": "2024-01-20T14:45:00Z"
}
Champs de la requête
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
name |
string | Oui | Nom du carnet |
description |
string | Non | Description du carnet |
notebookOrder |
decimal | Non | Ordre d'affichage |
dateModified |
datetime | Non | Pour verrouillage optimiste |
Réponse (200 OK)
Retourne le carnet mis à jour.
Verrouillage optimiste
Si dateModified est fourni et ne correspond pas à la valeur actuelle du serveur, renvoie 409 Conflict :
{
"Error": "CONFLICT",
"Message": "Le carnet a été modifié par un autre utilisateur depuis votre dernière récupération",
"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} pour récupérer l'état actuel, puis réessayer"
}
Supprimer un Carnet de Notes
DELETE /api/{tenantId}/{projectId}/notebook/{notebookId}
Supprime définitivement un carnet de notes et tous ses blocs.
Paramètres de chemin
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
tenantId |
GUID | Oui | Identifiant du locataire |
projectId |
GUID | Oui | Identifiant du projet |
notebookId |
GUID | Oui | Identifiant du carnet |
Réponse (200 OK)
{
"Message": "Carnet supprimé avec succès",
"NotebookId": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
}
Copier un Carnet de Notes
POST /api/{tenantId}/{projectId}/notebook/{notebookId}/copy
Crée une copie complète d'un carnet, incluant tous les blocs. Peut copier vers la même ou une autre investigation.
Paramètres de chemin
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
tenantId |
GUID | Oui | Identifiant du locataire |
projectId |
GUID | Oui | Identifiant du projet |
notebookId |
GUID | Oui | Identifiant du carnet source |
Corps de la requête
{
"name": "Copie de l'Analyse Principale",
"destinationInvestigationId": "22222222-3333-4444-5555-666666666666"
}
Champs de la requête
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
name |
string | Non | Nom de la copie (par défaut : "Copie de ") |
destinationInvestigationId |
GUID | Non | Investigation cible (par défaut : même investigation) |
Réponse (201 Created)
Retourne la copie nouvellement créée du carnet.
Obtenir l'URL Partageable
GET /api/{tenantId}/{projectId}/notebook/{notebookId}/url
Génère une URL partageable pour un accès direct au carnet dans l'interface utilisateur.
Réponse (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
}
Exemples d'Implémentation
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):
"""Liste tous les carnets d'une investigation."""
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):
"""Obtient les détails d'un carnet."""
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):
"""Crée un nouveau carnet."""
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):
"""Crée un carnet à partir d'un modèle."""
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):
"""Met à jour un carnet avec verrouillage optimiste."""
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"Conflit : {conflict['Message']}")
response.raise_for_status()
return response.json()
def delete_notebook(self, notebook_id):
"""Supprime un carnet."""
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):
"""Copie un carnet."""
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()
# Utilisation
manager = NotebookManager('your-api-key')
investigation_id = '11111111-2222-3333-4444-555555555555'
# Liste des carnets
notebooks = manager.list_notebooks(investigation_id)
print(f"{len(notebooks)} carnets trouvés")
# Création d'un carnet
notebook = manager.create_notebook(investigation_id, 'Nouvelle Analyse', 'Mon flux de travail')
print(f"Carnet créé : {notebook['notebookId']}")
# Copier le carnet
copy = manager.copy_notebook(notebook['notebookId'], 'Copie de Nouvelle Analyse')
print(f"Copie créée : {copy['notebookId']}")
# Mise à jour avec verrouillage optimiste
try:
updated = manager.update_notebook(
notebook['notebookId'],
'Analyse renommée',
date_modified=notebook['dateModified']
)
except Exception as e:
print(f"Mise à jour échouée : {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(`Échec : ${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(`Échec : ${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(`Conflit : ${conflict.Message}`);
}
if (!response.ok) throw new Error(`Échec : ${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(`Échec : ${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(`Échec : ${response.status}`);
return response.json();
}
}
// Utilisation
const manager = new NotebookManager('your-api-key');
const investigationId = '11111111-2222-3333-4444-555555555555';
// Liste des carnets
const notebooks = await manager.listNotebooks(investigationId);
console.log(`${notebooks.length} carnets trouvés`);
// Création et copie
const notebook = await manager.createNotebook(investigationId, 'Nouvelle Analyse');
const copy = await manager.copyNotebook(notebook.notebookId, 'Copie de l\'Analyse');
Bonnes Pratiques
- Chargement automatique : Ne chargez pas explicitement les projets pour les opérations CRUD sur les carnets - c'est automatique
- Verrouillage optimiste : Incluez
dateModifieddans les mises à jour pour détecter les conflits - Modèles : Utilisez des modèles pour des flux d'analyse cohérents
- Nommage : Utilisez des noms descriptifs et uniques dans chaque investigation
- Nettoyage : Supprimez les carnets inutilisés pour garder les investigations organisées