Skip to main content

Implementation Features

FeatureSupportNotes
Compartment Search✅ FullSingle resource type or all types (*)
GET Search✅ FullQuery string parameters
POST Search✅ FullForm-urlencoded body
CompartmentDefinition Hook✅ FullAutomatic membership table updates
Temporal Boundaries✅ FullstartParam and endParam support
Multiple Parameters✅ FullOR logic for membership parameters
Dynamic Configuration✅ FullRuntime updates via CompartmentDefinition resources
All Search Features✅ FullIncludes, pagination, filters work within compartments

Endpoints

TLQ FHIR supports the standard FHIR compartment search endpoints:
ScopeGETPOSTNotes
Specific Type/fhir/{Compartment}/{id}/{ResourceType}/fhir/{Compartment}/{id}/{ResourceType}/_searchSearch one resource type
All Types/fhir/{Compartment}/{id}/*/fhir/{Compartment}/{id}/_searchSearch all compartment types
Examples:
# Search for Observations in Patient/123's compartment
curl "http://localhost:8080/fhir/Patient/123/Observation?code=http://loinc.org|29463-7"

# Search for all resources in Patient/123's compartment
curl "http://localhost:8080/fhir/Patient/123/*"

# POST-based compartment search
curl -X POST "http://localhost:8080/fhir/Patient/123/Observation/_search" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "code=http://loinc.org|29463-7&status=final"

# All-types compartment search with type filtering
curl "http://localhost:8080/fhir/Patient/123/*?_type=Observation,Condition"
The literal * in the URL path means “all resource types in this compartment”. For POST searches, use the /_search endpoint without the *.

How Compartments Work

Compartment Membership

Resources belong to a compartment when they reference the compartment resource through specific search parameters. For example:
  • Patient Compartment: Resources with patient, subject, or performer parameters pointing to a Patient
  • Encounter Compartment: Resources with encounter or context parameters pointing to an Encounter
  • Device Compartment: Resources with device or subject parameters pointing to a Device

CompartmentDefinition Resources

TLQ FHIR uses CompartmentDefinition resources to define compartment membership rules. When you create or update a CompartmentDefinition, the server automatically:
  1. Parses the compartment type (e.g., “Patient”, “Encounter”)
  2. Extracts resource membership rules from the resource[] array
  3. Updates the compartment_memberships database table
  4. Enables compartment searches for that compartment type
Example CompartmentDefinition:
{
  "resourceType": "CompartmentDefinition",
  "id": "patient",
  "code": "Patient",
  "search": true,
  "resource": [
    {
      "code": "Patient",
      "param": ["{def}"]
    },
    {
      "code": "Observation",
      "param": ["patient", "performer"]
    },
    {
      "code": "DiagnosticReport",
      "param": ["subject"]
    },
    {
      "code": "Account",
      "param": ["patient"],
      "startParam": "period",
      "endParam": "period"
    }
  ]
}

Special Parameter Values

  • {def}: The compartment resource itself (e.g., Patient in Patient compartment)
  • Multiple parameters: OR logic - resource is in compartment if ANY parameter matches
  • Empty param array: Resource type is NOT in this compartment

Temporal Boundaries

Some resources have time-based membership using startParam and endParam:
{
  "code": "Account",
  "param": ["patient"],
  "startParam": "period",
  "endParam": "period"
}
This means an Account is only in the Patient compartment during its period date range.

Database Schema

TLQ FHIR stores compartment membership rules in the compartment_memberships table:
CREATE TABLE compartment_memberships (
    compartment_type VARCHAR(64) NOT NULL,     -- e.g., "Patient", "Encounter"
    resource_type VARCHAR(64) NOT NULL,        -- e.g., "Observation", "Condition"
    parameter_names TEXT[] NOT NULL,           -- e.g., ["patient", "subject"]
    start_param VARCHAR(64),                   -- Optional temporal boundary
    end_param VARCHAR(64),                     -- Optional temporal boundary
    loaded_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    PRIMARY KEY (compartment_type, resource_type)
);

Search Examples

# Find all Observations for Patient/123
curl "http://localhost:8080/fhir/Patient/123/Observation"

# Find final lab results for Patient/123
curl "http://localhost:8080/fhir/Patient/123/Observation?category=laboratory&status=final"

# Find all resources in Patient/123's compartment
curl "http://localhost:8080/fhir/Patient/123/*"

Advanced Search Features

All standard FHIR search features work within compartments:
# Compartment search with includes
curl "http://localhost:8080/fhir/Patient/123/DiagnosticReport?_include=DiagnosticReport:result"

# Compartment search with pagination
curl "http://localhost:8080/fhir/Patient/123/Observation?_count=10"

# Compartment search with chaining
curl "http://localhost:8080/fhir/Patient/123/DiagnosticReport?result.code=http://loinc.org|33747-0"

# Compartment search with _filter
curl -G "http://localhost:8080/fhir/Patient/123/Observation" \
  --data-urlencode '_filter=status eq final and category co laboratory'

# Compartment search with summary
curl "http://localhost:8080/fhir/Patient/123/Observation?_summary=count"
# Search specific types in compartment
curl "http://localhost:8080/fhir/Patient/123/*?_type=Observation,Condition,DiagnosticReport"

# Exclude certain types (using _filter)
curl -G "http://localhost:8080/fhir/Patient/123/*" \
  --data-urlencode '_filter=not (resourceType eq AuditEvent)'

Managing CompartmentDefinitions

Creating a CompartmentDefinition

curl -X POST "http://localhost:8080/fhir/CompartmentDefinition" \
  -H "Content-Type: application/fhir+json" \
  -d '{
    "resourceType": "CompartmentDefinition",
    "id": "encounter",
    "code": "Encounter",
    "search": true,
    "resource": [
      {
        "code": "Encounter",
        "param": ["{def}"]
      },
      {
        "code": "Observation",
        "param": ["encounter", "context"]
      },
      {
        "code": "DiagnosticReport",
        "param": ["encounter", "context"]
      }
    ]
  }'

Updating Compartment Rules

When you update a CompartmentDefinition, TLQ FHIR automatically:
  1. Clears existing membership rules for that compartment type
  2. Rebuilds the rules from the updated definition
  3. Applies changes immediately to new searches
curl -X PUT "http://localhost:8080/fhir/CompartmentDefinition/encounter" \
  -H "Content-Type: application/fhir+json" \
  -d '{
    "resourceType": "CompartmentDefinition",
    "id": "encounter",
    "code": "Encounter",
    "search": true,
    "resource": [
      {
        "code": "Encounter",
        "param": ["{def}"]
      },
      {
        "code": "Observation",
        "param": ["encounter"]
      }
    ]
  }'

Deleting CompartmentDefinitions

Per FHIR spec, servers may continue using compartment definitions even after deletion. TLQ FHIR keeps the membership rules unless explicitly replaced:
# This deletes the CompartmentDefinition resource but keeps the compartment functional
curl -X DELETE "http://localhost:8080/fhir/CompartmentDefinition/encounter"
To fully disable a compartment, create a CompartmentDefinition with an empty resource array.

Configuration

Compartment search can be disabled in the server configuration:
fhir:
  interactions:
    compartment:
      search: false # Disable compartment search endpoints

Performance Considerations

  • Indexing: TLQ FHIR uses GIN indexes on parameter_names for efficient membership queries
  • Caching: Compartment membership rules are loaded once per search and cached
  • Query Optimization: The search engine builds optimized SQL queries with proper JOINs
  • Resource Types: Searching specific resource types is more efficient than all-types searches

Limitations

  • Compartment Instance Validation: TLQ FHIR does not validate that the compartment resource (e.g., Patient/123) exists
  • Empty Results: Non-existent compartment instances return empty search results rather than errors
  • Temporal Boundaries: Currently stored but not yet fully implemented in search logic

Error Handling

# Unknown compartment type
curl "http://localhost:8080/fhir/UnknownType/123/Observation"
# Returns: 400 Bad Request - Unsupported resource type

# Unknown resource type in compartment
curl "http://localhost:8080/fhir/Patient/123/UnknownType"
# Returns: 400 Bad Request - Unsupported resource type

# Malformed compartment ID
curl "http://localhost:8080/fhir/Patient//Observation"
# Returns: 404 Not Found