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 Field Definitions (PF-16)
Created: 2025-01-27
Status: ✅ Complete

Quick Reference

When to Use Custom Fields:
  • ✅ You need to extend an existing entity (hr_employees, rh_residents, etc.)
  • ✅ Field is organization-specific (not core to all organizations)
  • ✅ Field is metadata (not frequently queried)
  • ✅ Field applies to all records of that entity type
When NOT to Use Custom Fields:
  • ❌ You need a new entity type → Use Custom Objects (PF-24)
  • ❌ You need a field in a form → Use Form Fields (FW-01)
  • ❌ You need to control field visibility → Use Entity Field Configuration (PF-17)
  • ❌ Field is frequently queried → Use proper column (not custom_fields)

What Are Custom Fields?

Custom Fields are organization-specific metadata that extend existing entity schemas without code changes. They are stored in custom_fields JSONB columns on entity tables. Key Characteristics:
  • Organization-scoped (each org defines their own)
  • Stored in JSONB (flexible, not indexed by default)
  • Defined via UI (no code changes needed)
  • Inherit entity RLS policies (no separate security)
Storage: {entity_table}.custom_fields JSONB column

Common Use Cases

Use Case 1: Employee Badge Number

Scenario: Your organization issues physical badge numbers to employees, and you need to track them. Solution: Create Custom Field Definition (PF-16) Why Custom Fields:
  • Extending existing entity (hr_employees)
  • Organization-specific (not all orgs use badge numbers)
  • Metadata (not frequently queried)
  • Applies to all employees
Implementation:
  1. Go to Settings → Custom Fields
  2. Select entity: hr_employees
  3. Create field:
    • Field Key: badge_number
    • Field Label: “Badge Number”
    • Field Type: text
    • Validation: Pattern ^[A-Z]{3}-\d{4}$ (e.g., “EMP-1234”)
  4. Save definition
  5. Field appears in all employee forms/views
Storage: hr_employees.custom_fields->>'badge_number' Not Form Fields Because:
  • Not form-specific (applies to all employee records)
  • Not one-time data capture (badge number is employee attribute)

Use Case 2: Resident External Case ID

Scenario: Your organization integrates with external case management system and needs to store external case IDs. Solution: Create Custom Field Definition (PF-16) Why Custom Fields:
  • Extending existing entity (rh_residents)
  • Organization-specific (external system integration)
  • Metadata (integration reference)
  • Applies to all residents
Implementation:
  1. Go to Settings → Custom Fields
  2. Select entity: rh_residents
  3. Create field:
    • Field Key: external_case_id
    • Field Label: “External Case ID”
    • Field Type: text
    • Validation: Required
  4. Save definition
  5. Field appears in resident forms/views
Storage: rh_residents.custom_fields->>'external_case_id'

Use Case 3: Document Retention Policy

Scenario: Your organization has specific document retention policies that vary by document type. Solution: Create Custom Field Definition (PF-16) Why Custom Fields:
  • Extending existing entity (pf_documents)
  • Organization-specific (retention policies vary)
  • Metadata (policy reference)
  • Applies to all documents
Implementation:
  1. Go to Settings → Custom Fields
  2. Select entity: pf_documents
  3. Create field:
    • Field Key: retention_years
    • Field Label: “Retention Years”
    • Field Type: number
    • Validation: Min 1, Max 100
  4. Save definition
  5. Field appears in document forms/views
Storage: pf_documents.custom_fields->>'retention_years'

When NOT to Use Custom Fields

❌ Don’t Use Custom Fields For: New Entity Types

Example: “I need to track Clinical Licenses” Why Not Custom Fields:
  • Not extending existing entity
  • Need new entity type (Clinical Licenses)
  • Need multiple records (not just metadata on existing records)
Use Instead: Custom Objects (PF-24)

❌ Don’t Use Custom Fields For: Form-Specific Fields

Example: “I need a field in my intake form” Why Not Custom Fields:
  • Not extending entity schema
  • Form-specific field (not entity attribute)
  • One-time data capture (form submission)
Use Instead: Form Fields (FW-01)

❌ Don’t Use Custom Fields For: Frequently-Queried Data

Example: “I need to query employees by employment status frequently” Why Not Custom Fields:
  • Frequently queried (needs index)
  • Core business data (not organization-specific metadata)
  • Performance critical
Use Instead: Proper column (e.g., hr_employees.employment_status)

❌ Don’t Use Custom Fields For: Sensitive Data

Example: “I need to store SSN in custom fields” Why Not Custom Fields:
  • Sensitive data (requires encryption, special handling)
  • Security/compliance requirements
Use Instead: Encrypted column or separate secure table

Integration with Other Systems

Custom Fields + Entity Field Configuration (PF-17)

Use Case: Control visibility of custom fields in entity forms Example: Hide badge_number from non-admins Implementation:
  1. Define custom field (PF-16)
  2. Configure field visibility (PF-17):
    • Entity: hr_employees
    • View Context: edit_form
    • Field: badge_number (custom field)
    • Visible to roles: [org_admin, hr_manager]
  3. Field only visible to admins/managers
Benefits:
  • Custom fields respect field configuration
  • Role-based visibility control

Custom Fields + Picklists (PF-15)

Use Case: Custom field needs dropdown values Example: Employee shirt size (S, M, L, XL) Implementation:
  1. Create picklist in Settings → Picklists:
    • Name: employee_shirt_sizes
    • Items: S, M, L, XL
  2. Create custom field (PF-16):
    • Entity: hr_employees
    • Field Key: shirt_size
    • Field Type: select
    • Picklist: employee_shirt_sizes
  3. Field renders as dropdown with picklist values
Benefits:
  • Reusable picklist values
  • Consistent values across system

Custom Fields + Forms (FW-01)

Use Case: Form needs to capture custom field value Example: Intake form that captures badge_number Implementation:
  1. Define custom field (PF-16) for hr_employees
  2. Create form (FW-01) with field that maps to custom field
  3. On form submission, save value to employee.custom_fields.badge_number
Note: This is advanced - typically forms capture data in form_submissions, not directly in entity custom_fields.

Custom Fields + Raw Data Editor (PF-25)

Use Case: Browse and edit custom field values in bulk Example: Update badge numbers for multiple employees Implementation:
  1. Go to Settings → Data Manager
  2. Select “Employees” object
  3. Click “Raw Data” tab
  4. Custom fields appear as editable columns
  5. Click any custom field cell to edit inline
  6. Save changes in batch
Benefits:
  • Bulk editing without opening each record
  • Export custom field values to CSV

Decision Tree

I need to add a field
├─ Is this for an existing entity (hr_employees, rh_residents, etc.)?
│  ├─ Yes → Is this organization-specific metadata?
│  │   ├─ Yes → Is this frequently queried?
│  │   │   ├─ No → Use Custom Fields (PF-16) ✅
│  │   │   └─ Yes → Use proper column (not custom_fields)
│  │   └─ No → Is this core business data?
│  │       └─ Yes → Use proper column (not custom_fields)
│  └─ No → Is this for a form?
│       ├─ Yes → Use Form Fields (FW-01) ✅
│       └─ No → Is this for a new entity type?
│            └─ Yes → Use Custom Objects (PF-24) ✅

Examples by Entity Type

HR Employees

  • Badge Number: Physical badge ID
  • Building Access: List of buildings employee can access
  • Shift Code: Employee shift assignment code
  • Payroll ID: External payroll system ID
  • Shirt Size: Uniform size

RH Residents

  • External Case ID: Integration with external case management
  • Funding Source: Source of funding for resident
  • Phase: Custom resident phase (organization-specific)
  • Emergency Contact Verified: Verification status

FA Invoices

  • Cost Center: Organization-specific cost center code
  • Project Code: Project tracking code
  • Approval Chain: Custom approval workflow metadata
  • External Invoice ID: Integration with external system

FW Form Submissions

  • Priority: Submission priority level
  • SLA Deadline: Service level agreement deadline
  • External Case ID: Integration reference
  • Workflow State: Custom workflow state

Best Practices

1. Use Descriptive Field Keys

Do: Use snake_case, descriptive keys (badge_number, external_case_id)
Don’t: Use abbreviations (badge, ext_id)

2. Add Validation Rules

Do: Add validation (required, patterns, min/max)
Don’t: Leave fields unvalidated

3. Use Picklists for Select Fields

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

4. Document Field Purpose

Do: Add description and help text
Don’t: Leave fields undocumented

5. Consider Performance

Do: Use custom fields for metadata (not frequently queried)
Don’t: Use custom fields for performance-critical queries

Common Mistakes

Mistake 1: Using Custom Fields for New Entity Types

Problem: Creating custom fields to track Clinical Licenses
Solution: Use Custom Objects (PF-24) instead

Mistake 2: Using Custom Fields for Form-Specific Data

Problem: Creating custom field for form question
Solution: Use Form Fields (FW-01) instead

Mistake 3: Not Using Validation

Problem: Custom fields accept invalid data
Solution: Add validation rules (required, patterns, min/max)

Mistake 4: Using Custom Fields for Frequently-Queried Data

Problem: Querying custom_fields in dashboard (slow)
Solution: Promote to proper column or add GIN index

Performance Considerations

When to Add GIN Index

Add GIN index if:
  • Frequently filtering by custom field
  • Complex JSONB queries (containment, existence)
  • Query performance p95 > 500ms
Example:
CREATE INDEX idx_hr_employees_custom_fields 
ON hr_employees USING GIN (custom_fields);

When to Promote to Column

Promote to column if:
  • Field is frequently queried
  • Field is core business data (not org-specific)
  • Performance is critical
Example: employment_status should be column, not custom field.

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