> ## 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.

# Use Case Guide: Custom Fields

> System: Platform Foundation (PF) Feature: Custom Field Definitions (PF-16) Created: 2025-01-27 Status: ✅ Complete

**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:**

```sql theme={null}
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.

***

## Related Documentation

* [PF-16: Custom Field Definitions Spec](../../../specs/pf/specs/PF-16-custom-field-definitions.md)
* [PF-17: Entity Field Configuration Spec](../../../specs/pf/specs/PF-17-entity-field-configuration.md)
* [PF-15: Picklist System Spec](../../../specs/pf/specs/PF-15-picklist-system.md)
* [Field Configuration Use Case Guide](./field-configuration.md)
* [Clarity Analysis](./clarity-analysis.md)

***

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