[BREAKING-CHANGE] Add NOT_RECORDED call recording status (#23478)

Adds NOT_RECORDED to the CallRecording status select, for meetings where
nothing was captured (bot never admitted, meeting not started, nobody
joined). First part of twentyhq/core-team-issues#2706, split out so
existing workspaces are upgraded before the call-recorder app starts
writing the new status.

- NOT_RECORDED enum value + standard select option
- 2-26 workspace upgrade command adding the option to existing
workspaces (idempotent, same option id as the standard definition)

App-side classification from Recall sub codes comes in a follow-up PR.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/23478?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
This commit is contained in:
nitin
2026-07-29 20:14:51 +05:30
committed by GitHub
parent 4ec65ed08d
commit 742f76e318
7 changed files with 212 additions and 3 deletions
@@ -2,8 +2,10 @@ import {
STANDARD_OBJECTS,
STANDARD_PAGE_LAYOUT_UNIVERSAL_IDENTIFIERS,
} from 'twenty-shared/metadata';
import { type FieldMetadataType } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type';
import { computeTwentyStandardApplicationAllFlatEntityMaps } from 'src/engine/workspace-manager/twenty-standard-application/utils/twenty-standard-application-all-flat-entity-maps.constant';
@@ -36,6 +38,23 @@ describe('CallRecording standard metadata build', () => {
expect(callRecording?.isSystem).toBe(true);
});
it('offers the full recording lifecycle as status options', () => {
const statusField = allFlatEntityMaps.flatFieldMetadataMaps
.byUniversalIdentifier[
STANDARD_OBJECTS.callRecording.fields.status.universalIdentifier
] as FlatFieldMetadata<FieldMetadataType.SELECT> | undefined;
expect(statusField?.options?.map((option) => option.value)).toEqual([
'SCHEDULED',
'JOINING',
'RECORDING',
'PROCESSING',
'COMPLETED',
'FAILED',
'NOT_RECORDED',
]);
});
it('links callRecording to a calendarEvent through a direct relation', () => {
const calendarEventField =
allFlatEntityMaps.flatFieldMetadataMaps.byUniversalIdentifier[
@@ -178,6 +178,13 @@ export const buildCallRecordingStandardFlatFieldMetadatas = ({
position: 5,
color: 'gray',
},
{
id: 'cbd14df8-9cc2-4399-92f5-31fc41f3768b',
value: CallRecordingStatus.NOT_RECORDED,
label: i18nLabel(msg`Not recorded`),
position: 6,
color: 'yellow',
},
],
},
standardObjectMetadataRelatedEntityIds,