background-fields.ts2.4 KBView on GitHub /**
* Frontend background-field (sub-event taxonomy) visibility helpers.
*
* Org custom fields can be flagged `background === true`. Those are internal
* sub-event taxonomy "moments" (discovery questions, objections, MEDDPICC
* signals) extracted for analysis — they must NEVER surface in normal
* field-display UI: CRM/canvas/sidebar columns, group-by and field-mapping
* pickers, the conversation overview grid, or the working-memory card.
*
* The dedicated taxonomy editor (IntelligenceFieldsEditor) is the one surface
* that deliberately shows background fields; it reads them directly rather than
* through these helpers.
*
* Mirrors the server-side source of truth in
* `apps/server/src/services/field-values/background-fields.ts`.
*/
/** A field definition is "background" (hidden taxonomy moment) when `background === true`. */
export function isBackgroundField(field: { background?: boolean } | null | undefined): boolean {
return field?.background === true;
}
/**
* Strip background (sub-event taxonomy) fields from a field-definitions map,
* returning only the user-visible definitions. Preserves the key → definition
* shape so every column/picker/overview consumer can drop this in where it
* currently reads `aop.customFieldDefinitions`.
*/
export function getVisibleFieldDefinitions<T extends { background?: boolean }>(
defs: Record<string, T> | null | undefined,
): Record<string, T> {
const out: Record<string, T> = {};
for (const [id, field] of Object.entries(defs ?? {})) {
if (!isBackgroundField(field)) out[id] = field;
}
return out;
}
/**
* Collect the set of background field IDs across many AOPs.
*
* Working-memory *values* (`WorkingMemoryEntry`) carry no `background` flag, so
* they can only be identified via a field definition. When a given
* conversation's own AOP defs are unavailable (no `aopId`, or an other-org AOP
* whose minimal fetch failed), this org-wide set — background taxonomy IDs are
* canonical and shared across an org's AOPs — still lets callers keep background
* values hidden instead of falling back to showing everything.
*/
export function collectBackgroundFieldIds(
aops: Array<{ customFieldDefinitions?: Record<string, { background?: boolean }> | null }>,
): Set<string> {
const ids = new Set<string>();
for (const aop of aops) {
for (const [id, def] of Object.entries(aop.customFieldDefinitions ?? {})) {
if (isBackgroundField(def)) ids.add(id);
}
}
return ids;
}