Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt

Use this file to discover all available pages before exploring further.

System: Platform Foundation (PF)
Feature: Custom Objects (PF-24)
Created: 2025-01-27
Status: ✅ Complete

Quick Reference

When to Use Custom Objects:
  • ✅ You need a new entity type (not extending existing entity)
  • ✅ You need to track multiple records over time
  • ✅ You need CRUD operations (create, read, update, delete)
  • ✅ You need to query and report on records
When NOT to Use Custom Objects:
  • ❌ You need to extend existing entity → Use Custom Fields (PF-16)
  • ❌ You need to create a form → Use Form Builder (FW-01)
  • ❌ You need one-time data capture → Use Forms (FW-01)

What Are Custom Objects?

Custom Objects allow organizations to create new entity types beyond core Encore Health OS objects. They provide:
  • Custom object definitions (name, API name, category)
  • Field definitions (using PF-16)
  • Record management (CRUD operations)
  • Data storage (JSONB with GIN indexing)
Key Characteristics:
  • Organization-scoped (each org creates their own)
  • Flexible schema (fields defined via UI)
  • JSONB storage (flexible, indexed)
  • Appears in Data Manager (PF-23)
Storage: pf_custom_objects (definitions) + pf_custom_object_records (data)

Common Use Cases

Use Case 1: Clinical Licenses Tracking

Scenario: Your organization needs to track clinical licenses (RN, LCSW, LPC, etc.) for employees with fields like license number, expiration date, renewal status. Solution: Create Custom Object (PF-24) Why Custom Objects:
  • New entity type (not extending existing entity)
  • Need to track multiple records over time (one employee can have multiple licenses)
  • Need CRUD operations (add license, update expiration, renew license)
  • Need to query and report (find expiring licenses, license compliance report)
Implementation:
  1. Navigate to Settings → Data Manager
  2. Click “Create Custom Object”
  3. Enter object details:
    • Name: “Clinical Licenses”
    • API Name: clinical_licenses
    • Category: HR & Workforce
    • Description: “Track clinical licenses and certifications for staff”
  4. Add fields:
    • Employee (lookup to hr_employees)
    • License Type (select, picklist: license_types)
    • License Number (text, required)
    • Issue Date (date)
    • Expiration Date (date, required)
    • Status (select, picklist: license_status)
    • Renewal Date (date)
  5. Save object
  6. Create records for each license
  7. Query records (e.g., find licenses expiring in 30 days)
Not Forms Because:
  • Not one-time data capture (tracking records over time)
  • Need CRUD operations (not just submissions)
  • Need to query and report on records
Not Custom Fields Because:
  • Not extending existing entity (hr_employees)
  • New entity type (licenses are separate from employees)

Use Case 2: Training Classes Management

Scenario: Your organization needs to track training classes with enrollment, scheduling, and completion tracking. Solution: Create Custom Object (PF-24) Why Custom Objects:
  • New entity type (training classes)
  • Need to track multiple records (multiple classes)
  • Need CRUD operations (create class, enroll employees, mark completion)
  • Need to query and report (upcoming classes, enrollment reports)
Implementation:
  1. Create custom object: “Training Classes”
  2. Add fields:
    • Class Name (text, required)
    • Instructor (lookup to hr_employees)
    • Date (date, required)
    • Duration Hours (number)
    • Max Participants (number)
    • Location (select, picklist: sites)
    • Status (select, picklist: class_status)
  3. Create records for each class
  4. Link to employees via enrollment (separate relationship or custom field)
Not Forms Because:
  • Not one-time data capture (tracking classes over time)
  • Need CRUD operations (not just submissions)

Use Case 3: Fleet Management

Scenario: Your organization needs to track vehicles (cars, vans) with maintenance, registration, and usage tracking. Solution: Create Custom Object (PF-24) Why Custom Objects:
  • New entity type (vehicles)
  • Need to track multiple records (multiple vehicles)
  • Need CRUD operations (add vehicle, update maintenance, track usage)
  • Need to query and report (maintenance schedule, registration expiration)
Implementation:
  1. Create custom object: “Fleet Vehicles”
  2. Add fields:
    • Vehicle Type (select, picklist: vehicle_types)
    • Make (text)
    • Model (text)
    • Year (number)
    • License Plate (text, required)
    • Registration Expiration (date)
    • Last Maintenance Date (date)
    • Next Maintenance Date (date)
    • Status (select, picklist: vehicle_status)
  3. Create records for each vehicle
  4. Query records (e.g., find vehicles needing maintenance)

When NOT to Use Custom Objects

❌ Don’t Use Custom Objects For: Extending Existing Entities

Example: “I need to add badge_number to employees” Why Not Custom Objects:
  • Not creating new entity type
  • Extending existing entity (hr_employees)
  • Adding metadata field
Use Instead: Custom Fields (PF-16)

❌ Don’t Use Custom Objects For: Creating Forms

Example: “I need to create a resident intake form” Why Not Custom Objects:
  • Not creating new entity type
  • Creating data capture interface (form)
  • One-time data capture (form submission)
Use Instead: Form Builder (FW-01)

❌ Don’t Use Custom Objects For: One-Time Data Capture

Example: “I need to collect incident reports” Why Not Custom Objects:
  • One-time data capture (each submission is independent)
  • Not tracking records over time
  • Form submissions sufficient
Use Instead: Forms (FW-01)

Integration with Other Systems

Custom Objects + Custom Fields (PF-16)

Use Case: Custom object needs fields Example: Clinical Licenses object needs license fields Implementation:
  1. Create custom object (PF-24)
  2. Add fields using PF-16 field definitions
  3. Fields appear in object detail view
  4. Use fields in custom object records
Benefits:
  • Reuse PF-16 field definitions
  • Consistent field types and validation

Custom Objects + Picklists (PF-15)

Use Case: Custom object field needs dropdown values Example: License Type field needs license types (RN, LCSW, etc.) Implementation:
  1. Create picklist: license_types
  2. Create custom object field (PF-24)
  3. Select field type: select
  4. Choose picklist: license_types
  5. Field renders with picklist values
Benefits:
  • Reusable picklist values
  • Consistent values across system

Custom Objects + Data Manager (PF-23)

Use Case: Custom object appears in object browser Example: Clinical Licenses object appears in Data Manager Implementation:
  1. Create custom object (PF-24)
  2. Object automatically appears in Data Manager (PF-23)
  3. Browse, search, and manage object in Data Manager
  4. View object metadata, fields, records
Benefits:
  • Unified object discovery
  • Consistent object management

Custom Objects + Forms (FW-01)

Use Case: Form needs to reference custom object Example: Intake form needs to select clinical license Implementation:
  1. Create custom object: Clinical Licenses (PF-24)
  2. Create form (FW-01)
  3. Add lookup field (FW-15):
    • Data Source: Table Lookup
    • Table: pf_custom_object_records (filtered by custom_object_id)
  4. Form renders with licenses from custom object
Benefits:
  • Forms can reference custom objects
  • Real-time data from custom objects

Decision Tree

I need to track data
├─ Is this a new entity type (not extending existing entity)?
│  ├─ Yes → Do I need to track multiple records over time?
│  │   ├─ Yes → Do I need CRUD operations?
│  │   │   ├─ Yes → Use Custom Objects (PF-24) ✅
│  │   │   │   Example: Clinical Licenses, Training Classes
│  │   │   └─ No → Is this one-time data capture?
│  │   │       └─ Yes → Use Forms (FW-01) ✅
│  │   └─ No → Is this one-time data capture?
│  │       └─ Yes → Use Forms (FW-01) ✅
│  └─ No → Is this extending an existing entity?
│       └─ Yes → Use Custom Fields (PF-16) ✅

Examples by Industry

Healthcare/Behavioral Health

  • Clinical Licenses: Track RN, LCSW, LPC licenses
  • Certifications: Track CPR, First Aid, specialized certifications
  • Training Classes: Track mandatory training sessions
  • Equipment: Track medical equipment inventory

Recovery Housing

  • Program Phases: Track resident program phases
  • Support Services: Track support service types
  • Facility Inspections: Track inspection records
  • Funding Sources: Track funding source types

Multi-Site Operations

  • Site-Specific Policies: Track policies per site
  • Local Regulations: Track local compliance requirements
  • Site Equipment: Track equipment per site
  • Site Contacts: Track site-specific contacts

Best Practices

1. Use Descriptive API Names

Do: Use snake_case, descriptive names (clinical_licenses, training_classes)
Don’t: Use abbreviations (clin_lic, train_cls)

2. Add Object Descriptions

Do: Add descriptions to objects (help users understand purpose)
Don’t: Leave objects without descriptions

3. Use Appropriate Categories

Do: Assign objects to appropriate categories (HR, Finance, Operations)
Don’t: Leave objects uncategorized

4. Reuse Field Definitions

Do: Use PF-16 field definitions for custom object fields
Don’t: Create duplicate field definitions

5. Use Picklists for Select Fields

Do: Use picklists for dropdown values
Don’t: Hardcode options in field definitions

Common Mistakes

Mistake 1: Using Custom Objects for Forms

Problem: Creating custom object for intake form
Solution: Use Form Builder (FW-01) instead

Mistake 2: Using Custom Objects for Entity Extension

Problem: Creating custom object to add badge_number to employees
Solution: Use Custom Fields (PF-16) instead

Mistake 3: Not Using Field Definitions

Problem: Creating fields without PF-16 definitions
Solution: Use PF-16 field definitions for consistency

Mistake 4: Not Adding Descriptions

Problem: Objects without descriptions, unclear purpose
Solution: Add descriptions to all objects

Performance Considerations

JSONB Storage

  • Custom object records stored in pf_custom_object_records.data JSONB
  • GIN index for performance: CREATE INDEX ... USING GIN(data)
  • Efficient for flexible schema
  • Query performance: p95 < 500ms for 1000+ records

When to Promote to Core Entity

Promote if:
  • Object used by 80%+ of organizations
  • Performance critical (frequently queried)
  • Core business function (not organization-specific)
Example: If “Clinical Licenses” becomes core feature, promote to hr_licenses table.

Last Updated: 2025-12-05
Next Review: After user feedback