For AI agents: the documentation index is at /docs/aidbox/llms.txt. A Markdown version of this page is available at /docs/aidbox/notebooks.md or by requesting it with the Accept: text/markdown header.
Aidbox Docs
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
        };
    }
}