task-output.ts2.2 KBView on GitHub /**
* The task OUTPUT axis — what finishing a task actually produces.
*
* Mirrors `TASK_OUTPUT_KINDS` in apps/server/src/db/aop-schema.ts — keep in sync. This axis
* supersedes the old `taskChannel` declaration: `taskChannel` was written before the work
* happened, `taskOutput.kind` reflects what the task really produces, so where the two disagree
* the output kind wins. Note there is no `multi-action` kind — those tasks are `crm-field`,
* `crm-opportunity` or `none` on this axis.
*
* `taskOutput` is NULLABLE and null is a real state: "the output is not decided yet". Surfaces
* that bucket by kind must therefore give null a home of its own rather than folding it into
* email.
*/
export const TASK_OUTPUT_KINDS = [
'email',
'slack',
'calendar',
'linkedin',
'whatsapp',
'crm-field',
'crm-opportunity',
'file',
'recommendation',
'none',
] as const;
export type TaskOutputKind = (typeof TASK_OUTPUT_KINDS)[number];
/** Bucket key for a task whose output kind has not been decided yet (`taskOutput` is null). */
export const UNDECIDED_OUTPUT_KEY=[redacted];
/** Human labels for each output kind — shared by every surface that names one. */
export const TASK_OUTPUT_KIND_LABELS: Record<TaskOutputKind, string> = {
email: 'Email',
slack: 'Slack',
calendar: 'Calendar',
linkedin: 'LinkedIn',
whatsapp: 'WhatsApp',
'crm-field': 'CRM field',
'crm-opportunity': 'CRM opportunity',
file: 'File',
recommendation: 'Recommendation',
none: 'Reminder',
};
/** The minimum shape a task needs for its output kind to be read. */
export interface TaskWithOutput {
taskOutput?: { kind?: string | null } | null;
}
/** A task's output kind, or `undefined` when it has not been decided. */
export function taskOutputKind(task: TaskWithOutput): TaskOutputKind | undefined {
const kind = task.taskOutput?.kind;
return kind && (TASK_OUTPUT_KINDS as readonly string[]).includes(kind)
? (kind as TaskOutputKind)
: undefined;
}
/** Display label for a task's output kind; `Undecided` while the output has not been chosen. */
export function taskOutputLabel(task: TaskWithOutput): string {
const kind = taskOutputKind(task);
return kind ? TASK_OUTPUT_KIND_LABELS[kind] : 'Undecided';
}