All notebooks
Workflows using PlanDefinitions
Description
6 cells · updated Aug 11, 2025
This is a read-only view. Responses shown were saved when the notebook was published —
open it in your own Aidbox to run the cells against live data.
ActivityDefinition
REST
Send
Cells run only inside Aidbox. Use Run in Aidbox above to open this notebook in your own instance.
POST /fhir/ActivityDefinition
Content-Type: application/fhir+json
{
"resourceType": "ActivityDefinition",
"id": "simple-review-task",
"url": "http://example.org/fhir/ActivityDefinition/simple-review-task",
"version": "1.0.0",
"name": "SimpleReviewTask",
"title": "Simple Review Task",
"status": "active",
"description": "A simple task to review a document",
"kind": "Task",
"code": {
"coding": [
{
"system": "http://snomed.info/sct",
"code": "182836005",
"display": "Review of medication"
}
]
},
"intent": "proposal",
"priority": "routine",
"doNotPerform": false
}
Response:
Body
Status:
409
{
"resourceType": "OperationOutcome",
"id": "duplicate",
"text": {
"status": "generated",
"div": "ERROR: duplicate key value violates unique constraint \"activitydefinition_pkey\"\n Detail: Key (id)=(simple-review-task) already exists."
},
"issue": [
{
"severity": "fatal",
"code": "duplicate",
"diagnostics": "ERROR: duplicate key value violates unique constraint \"activitydefinition_pkey\"\n Detail: Key (id)=(simple-review-task) already exists."
}
]
}PlanDefinition
REST
Send
Cells run only inside Aidbox. Use Run in Aidbox above to open this notebook in your own instance.
POST /fhir/PlanDefinition
Content-Type: application/fhir+json
{
"resourceType": "PlanDefinition",
"id": "simple-plan",
"url": "http://example.org/fhir/PlanDefinition/simple-plan",
"version": "1.0.0",
"name": "SimplePlan",
"title": "Simple Document Review Plan",
"status": "active",
"description": "A simple plan to create a review task",
"type": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/plan-definition-type",
"code": "workflow-definition",
"display": "Workflow Definition"
}
]
},
"subjectCodeableConcept": {
"coding": [
{
"system": "http://hl7.org/fhir/resource-types",
"code": "Composition",
"display": "Composition"
}
]
},
"action": [
{
"id": "create-review-task",
"title": "Create Review Task",
"description": "Create a task to review the document",
"definitionCanonical": "http://example.org/fhir/ActivityDefinition/simple-review-task"
}
]
}
Response:
Body
Status:
201
{
"description": "A simple plan to create a review task",
"meta": {
"lastUpdated": "2025-08-11T10:36:28.405057Z",
"versionId": "139977",
"extension": [
{
"url": "https://aidbox.app/ex/createdAt",
"valueInstant": "2025-08-11T10:36:28.405057Z"
}
]
},
"subjectCodeableConcept": {
"coding": [
{
"code": "Composition",
"system": "http://hl7.org/fhir/resource-types",
"display": "Composition"
}
]
},
"name": "SimplePlan",
"type": {
"coding": [
{
"code": "workflow-definition",
"system": "http://terminology.hl7.org/CodeSystem/plan-definition-type",
"display": "Workflow Definition"
}
]
},
"resourceType": "PlanDefinition",
"title": "Simple Document Review Plan",
"status": "active",
"id": "simple-plan",
"url": "http://example.org/fhir/PlanDefinition/simple-plan",
"action": [
{
"id": "create-review-task",
"title": "Create Review Task",
"definitionCanonical": "http://example.org/fhir/ActivityDefinition/simple-review-task",
"description": "Create a task to review the document"
}
],
"version": "1.0.0"
}
REST
Send
Cells run only inside Aidbox. Use Run in Aidbox above to open this notebook in your own instance.
GET /fhir/PlanDefinition/simple-plan
Response:
Body
Status:
200
{
"description": "A simple plan to create a review task",
"meta": {
"lastUpdated": "2025-08-11T10:36:28.405057Z",
"versionId": "139977",
"extension": [
{
"url": "https://aidbox.app/ex/createdAt",
"valueInstant": "2025-08-11T10:36:28.405057Z"
}
]
},
"subjectCodeableConcept": {
"coding": [
{
"code": "Composition",
"system": "http://hl7.org/fhir/resource-types",
"display": "Composition"
}
]
},
"name": "SimplePlan",
"type": {
"coding": [
{
"code": "workflow-definition",
"system": "http://terminology.hl7.org/CodeSystem/plan-definition-type",
"display": "Workflow Definition"
}
]
},
"resourceType": "PlanDefinition",
"title": "Simple Document Review Plan",
"status": "active",
"id": "simple-plan",
"url": "http://example.org/fhir/PlanDefinition/simple-plan",
"action": [
{
"id": "create-review-task",
"title": "Create Review Task",
"definitionCanonical": "http://example.org/fhir/ActivityDefinition/simple-review-task",
"description": "Create a task to review the document"
}
],
"version": "1.0.0"
}Orchestrator Example
using Hl7.Fhir.Model;
using Hl7.Fhir.Rest;
using Task = System.Threading.Tasks.Task;
using FhirTask = Hl7.Fhir.Model.Task;
namespace Authoring.Services;
/// <summary>
/// Service to apply PlanDefinitions by creating workflow resources manually
/// </summary>
public class PlanDefinitionService
{
private readonly FhirClient _client;
public PlanDefinitionService(FhirClient client)
{
_client = client;
}
/// <summary>
/// Applies a PlanDefinition to a subject, creating CarePlan and Tasks
/// </summary>
/// <param name="planDefinitionId">PlanDefinition ID to apply</param>
/// <param name="subjectReference">Subject reference (e.g., "Composition/123")</param>
/// <returns>Bundle with created resources</returns>
public async Task<Bundle> ApplyAsync(string planDefinitionId, string subjectReference)
{
// 1. Get the PlanDefinition
var planDefinition = await _client.ReadAsync<PlanDefinition>($"PlanDefinition/{planDefinitionId}");
// 2. Create CarePlan
var carePlan = new CarePlan
{
Status = RequestStatus.Active,
Intent = CarePlan.CarePlanIntent.Plan,
Subject = new ResourceReference(subjectReference),
InstantiatesCanonical = new List<string> { planDefinition.Url }
};
var createdCarePlan = await _client.CreateAsync(carePlan);
// 3. Create Tasks from actions
var tasks = new List<FhirTask>();
foreach (var action in planDefinition.Action ?? new List<PlanDefinition.ActionComponent>())
{
var task = await CreateTaskFromActionAsync(action, planDefinition, subjectReference);
if (task != null) tasks.Add(task);
}
// 4. Return bundle with all created resources
var bundle = new Bundle
{
Type = Bundle.BundleType.Collection,
Entry = new List<Bundle.EntryComponent>()
};
bundle.Entry.Add(new Bundle.EntryComponent { Resource = createdCarePlan });
foreach (var task in tasks)
{
bundle.Entry.Add(new Bundle.EntryComponent { Resource = task });
}
return bundle;
}
/// <summary>
/// Gets existing tasks for a PlanDefinition and subject
/// </summary>
public async Task<List<FhirTask>> GetTasksAsync(string planDefinitionUrl, string subjectReference)
{
var searchParams = new SearchParams()
.Where($"instantiates-canonical={planDefinitionUrl}")
.Where($"for={subjectReference}");
var bundle = await _client.SearchAsync<FhirTask>(searchParams);
return bundle?.Entry?.Select(e => e.Resource).OfType<FhirTask>().ToList() ?? new List<FhirTask>();
}
private async Task<FhirTask?> CreateTaskFromActionAsync(PlanDefinition.ActionComponent action,
PlanDefinition planDefinition, string subjectReference)
{
var task = new FhirTask
{
Status = FhirTask.TaskStatus.Draft,
Intent = FhirTask.TaskIntent.Order,
For = new ResourceReference(subjectReference),
InstantiatesCanonical = planDefinition.Url,
Code = action.Code?.FirstOrDefault(),
Description = action.Description,
AuthoredOn = DateTimeOffset.Now.ToString("yyyy-MM-ddTHH:mm:sszzz")
};
// If action references an ActivityDefinition, get additional details
if (!string.IsNullOrEmpty(action.DefinitionCanonical))
{
try
{
var activityId = action.DefinitionCanonical.Split('/').Last();
var activityDef = await _client.ReadAsync<ActivityDefinition>($"ActivityDefinition/{activityId}");
task.Code = activityDef.Code ?? task.Code;
task.Priority = MapPriority(activityDef.Priority);
}
catch
{
// Continue with basic task if ActivityDefinition not found
}
}
return await _client.CreateAsync(task);
}
private RequestPriority? MapPriority(string? priority)
{
return priority?.ToLowerInvariant() switch
{
"routine" => RequestPriority.Routine,
"urgent" => RequestPriority.Urgent,
"stat" => RequestPriority.Stat,
_ => RequestPriority.Routine
};
}
}