Skip to main content

PPM Extensible Fields

PPM project and work item extensible fields are powered by the generic Foundation Extensible Fields (FND EFF) system. The same four-table model used across the platform — categories, attribute definitions, assignments, and values — handles custom fields for both PPM_PROJECT and PPM_WORK_ITEM entity types.

Why extensible fields exist​

Standard fields (title, status, dates, work) cover the universal aspects of project management. But organisations need custom fields too:

  • A construction company tracks contract type (lump sum, time and materials, cost plus)
  • A software team tracks story points and sprint on each work item
  • A compliance team tracks regulatory framework (SOX, GDPR, HIPAA) and audit status

These fields are organisation-specific, often type-specific (an epic might need "budget code" while a task needs "skill level"), and evolve as processes mature. Extensible fields let teams capture this variation at runtime without database migrations, while keeping the stored data typed, validated, and discoverable.

Extensible fields vs labels​

PPM provides both extensible fields (structured custom attributes) and labels (free-form tags). They serve different purposes:

AspectExtensible fieldsLabels
StructureTyped attributes with validationFree-form text tags
ScopeTenant-level definitions, assigned to entity typesTenant-scoped
PurposeStructured metadata for reporting and workflowsLightweight classification and filtering
ExampleRisk rating = "High"urgent, blocked, frontend

Use extensible fields when you need structured, validated, reportable metadata. Use labels when you need quick, informal classification. See Labels vs Extensible Fields for more on the distinction.

Entity types​

Two stable entity type codes identify PPM records in the FND EFF system:

Entity typeApplies toentity_id format
PPM_PROJECTProject recordsProject UUID
PPM_WORK_ITEMWork item recordsWork item UUID

Use these codes in fnd_categories.entity_type and fnd_category_assignments.entity_type when creating categories and assignments for PPM records.

Category scoping​

A category whose entity_type is PPM_PROJECT can only be assigned to projects; one with entity_type = 'PPM_WORK_ITEM' can only be assigned to work items. You cannot share a single category definition across both entity types. If the same logical attribute group applies to both, create two category definitions — one per entity type — with the same category_code prefix and distinct suffixes (e.g. RISK_PROJ and RISK_WI).

Optional subtype scoping​

Work items support an optional entity_subtype on fnd_category_assignments to restrict a category to a specific work item type (e.g. EPIC, ISSUE, TASK, BUG, MILESTONE). Omit entity_subtype to apply the category to all work item types.

POST /persist/v2/fnd_category_assignments
{
"category_id": "<category id>",
"entity_type": "PPM_WORK_ITEM",
"entity_subtype": "EPIC"
}

Projects do not have subtypes. Leave entity_subtype null for PPM_PROJECT assignments.

Attribute definitions​

Attributes follow the standard FND EFF data types. PPM attributes commonly use:

Data typeStored in columnTypical PPM use
TEXTtext_valueContract type, cost centre code, regulatory label
NUMBERnumber_valueBudget amount, story points, risk score
DATEdate_valueReview date, compliance deadline, approval date
BOOLEANboolean_valueApproval flags, compliance indicators
LOOKUPtext_valueRisk rating, status, priority from a controlled list

See Supported attribute types for the full list.

Primary category​

Each project and each work item may designate one category as its primary category. The primary_category_id column on the respective record points to an fnd_category_assignments.assignment_id. The primary category is used by the UI to surface the most important set of custom attributes in the record detail header.

  • ppm_projects.primary_category_id — the assignment that provides the project's primary custom attributes
  • ppm_work_items.primary_category_id — the assignment that provides the work item's primary custom attributes

primary_category_id is maintained automatically when data is migrated from the legacy PPM EFF tables. Consumers that set this field directly should reference a valid fnd_category_assignments.assignment_id whose entity_type matches the record type.

Assignments and values​

Before recording custom field values for a project or work item, a category must be explicitly assigned to the entity type. An assignment is required even when you know the category_id — there is no implicit link.

Assigning a category to projects​

POST /persist/v2/fnd_category_assignments
{
"category_id": "<category id>",
"entity_type": "PPM_PROJECT"
}

Assigning a category to work items (all types)​

POST /persist/v2/fnd_category_assignments
{
"category_id": "<category id>",
"entity_type": "PPM_WORK_ITEM"
}

Recording values for a project​

POST /persist/v2/fnd_category_values
[
{
"assignment_id": "<assignment id>",
"attr_id": "<attr id>",
"entity_id": "<project UUID>",
"text_value": "LUMP_SUM"
},
{
"assignment_id": "<assignment id>",
"attr_id": "<budget attr id>",
"entity_id": "<project UUID>",
"number_value": 250000
}
]

Recording values for a work item​

POST /persist/v2/fnd_category_values
[
{
"assignment_id": "<assignment id>",
"attr_id": "<risk attr id>",
"entity_id": "<work item UUID>",
"text_value": "HIGH"
},
{
"assignment_id": "<assignment id>",
"attr_id": "<review date attr id>",
"entity_id": "<work item UUID>",
"date_value": "2026-12-01"
}
]

Querying extensible fields​

All categories for PPM projects​

GET /persist/v2/fnd_categories?entity_type=eq.PPM_PROJECT&active=eq.true

All categories for PPM work items​

GET /persist/v2/fnd_categories?entity_type=eq.PPM_WORK_ITEM&active=eq.true

Attributes for a specific category​

GET /persist/v2/fnd_category_attrs?category_id=eq.<category id>&order=display_order.asc

All extensible field values for a project​

GET /persist/v2/fnd_category_values?entity_id=eq.<project UUID>&select=*,attr:fnd_category_attrs(attr_code,attr_name,data_type,display_order)

All extensible field values for a work item​

GET /persist/v2/fnd_category_values?entity_id=eq.<work item UUID>&select=*,attr:fnd_category_attrs(attr_code,attr_name,data_type,display_order)

Values grouped by category for a project​

GET /persist/v2/fnd_category_values?entity_id=eq.<project UUID>&select=*,attr:fnd_category_attrs(attr_code,attr_name,data_type,category_id),assignment:fnd_category_assignments(category_id,entity_type)

Updating a single value​

To update an existing value, PATCH using the value_id:

PATCH /persist/v2/fnd_category_values?value_id=eq.<value id>
{
"text_value": "MEDIUM"
}

To upsert (insert or update) using the natural key:

POST /persist/v2/fnd_category_values?on_conflict=entity_id,attr_id
{
"assignment_id": "<assignment id>",
"attr_id": "<attr id>",
"entity_id": "<project UUID>",
"text_value": "MEDIUM"
}

Access control​

PPM extensible fields follow the same authorisation rules as the records they extend:

  • Reads — permitted for users who can read the underlying project or work item
  • Writes — restricted to users with write permission on the project or work item
  • Category and attribute definitions — readable by all authenticated users; writeable only by tenant administrators