mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-21 16:27:18 +02:00
69 lines
2.1 KiB
TypeScript
69 lines
2.1 KiB
TypeScript
import type { Goal, Project } from "@paperclipai/shared";
|
|
|
|
export const ONBOARDING_PROJECT_NAME = "Onboarding";
|
|
|
|
function goalCreatedAt(goal: Goal) {
|
|
const createdAt = goal.createdAt instanceof Date ? goal.createdAt : new Date(goal.createdAt);
|
|
return Number.isNaN(createdAt.getTime()) ? 0 : createdAt.getTime();
|
|
}
|
|
|
|
function pickEarliestGoal(goals: Goal[]) {
|
|
return [...goals].sort((a, b) => goalCreatedAt(a) - goalCreatedAt(b))[0] ?? null;
|
|
}
|
|
|
|
export function selectDefaultCompanyGoalId(goals: Goal[]): string | null {
|
|
const companyGoals = goals.filter((goal) => goal.level === "company");
|
|
const rootGoals = companyGoals.filter((goal) => !goal.parentId);
|
|
const activeRootGoals = rootGoals.filter((goal) => goal.status === "active");
|
|
|
|
return (
|
|
pickEarliestGoal(activeRootGoals)?.id ??
|
|
pickEarliestGoal(rootGoals)?.id ??
|
|
pickEarliestGoal(companyGoals)?.id ??
|
|
null
|
|
);
|
|
}
|
|
|
|
export function buildOnboardingProjectPayload(goalId: string | null) {
|
|
return {
|
|
name: ONBOARDING_PROJECT_NAME,
|
|
status: "in_progress" as const,
|
|
...(goalId ? { goalIds: [goalId] } : {}),
|
|
};
|
|
}
|
|
|
|
export function selectReusableOnboardingProject<T extends Pick<Project, "name" | "status">>(
|
|
projects: T[],
|
|
): T | null {
|
|
return (
|
|
projects.find(
|
|
(project) =>
|
|
project.status !== "cancelled" &&
|
|
project.name.trim().toLowerCase() === ONBOARDING_PROJECT_NAME.toLowerCase(),
|
|
) ?? null
|
|
);
|
|
}
|
|
|
|
export function buildOnboardingIssuePayload(input: {
|
|
title: string;
|
|
description: string;
|
|
assigneeAgentId: string;
|
|
projectId: string;
|
|
goalId: string | null;
|
|
}) {
|
|
const title = input.title.trim();
|
|
const description = input.description.trim();
|
|
|
|
return {
|
|
title,
|
|
...(description ? { description } : {}),
|
|
assigneeAgentId: input.assigneeAgentId,
|
|
projectId: input.projectId,
|
|
...(input.goalId ? { goalId: input.goalId } : {}),
|
|
status: "todo" as const,
|
|
// Marks the single onboarding first task so the server seeds an agent
|
|
// greeting and the task-detail view suppresses the seeded-description bubble.
|
|
onboardingFirstTask: true,
|
|
};
|
|
}
|